国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java多線程打輔助的三個小伙子

pingink / 2133人閱讀

摘要:前言之前學多線程的時候沒有學習線程的同步工具類輔助類。而其它線程完成自己的操作后,調用使計數器減。信號量控制一組線程同時執行。

前言

之前學多線程的時候沒有學習線程的同步工具類(輔助類)。ps:當時覺得暫時用不上,認為是挺高深的知識點就沒去管了..

在前幾天,朋友發了一篇比較好的Semaphore文章過來,然后在瀏覽博客的時候又發現面試還會考,那還是挺重要的知識點。于是花了點時間去了解一下。

Java為我們提供了三個同步工具類

CountDownLatch(閉鎖)

CyclicBarrier(柵欄)

Semaphore(信號量)

這幾個工具類其實說白了就是為了能夠更好控制線程之間的通訊問題~

一、CountDownLatch 1.1CountDownLatch簡介

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

簡單來說:CountDownLatch是一個同步的輔助類,允許一個或多個線程一直等待直到其它線程完成它們的操作。

它常用的API其實就兩個:await()countDown()

使用說明:

count初始化CountDownLatch,然后需要等待的線程調用await方法。await方法會一直受阻塞直到count=0。而其它線程完成自己的操作后,調用countDown()使計數器count減1。當count減到0時,所有在等待的線程均會被釋放

說白了就是通過count變量來控制等待,如果count值為0了(其他線程的任務都完成了),那就可以繼續執行。

1.2CountDownLatch例子

例子:3y現在去做實習生了,其他的員工還沒下班,3y不好意思先走,等其他的員工都走光了,3y再走。

import java.util.concurrent.CountDownLatch;

public class Test {

    public static void main(String[] args) {

        final CountDownLatch countDownLatch = new CountDownLatch(5);

        System.out.println("現在6點下班了.....");

        // 3y線程啟動
        new Thread(new Runnable() {
            @Override
            public void run() {
           
                try {
                    // 這里調用的是await()不是wait()
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("...其他的5個員工走光了,3y終于可以走了");
            }
        }).start();

        // 其他員工線程啟動
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("員工xxxx下班了");
                    countDownLatch.countDown();
                }
            }).start();
        }
    }
}

輸出結果:

再寫個例子:3y現在負責倉庫模塊功能,但是能力太差了,寫得很慢,別的員工都需要等3y寫好了才能繼續往下寫。

import java.util.concurrent.CountDownLatch;

public class Test {

    public static void main(String[] args) {

        final CountDownLatch countDownLatch = new CountDownLatch(1);

        // 3y線程啟動
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("3y終于寫完了");
                countDownLatch.countDown();

            }
        }).start();

        // 其他員工線程啟動
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("其他員工需要等待3y");
                    try {
                        countDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("3y終于寫完了,其他員工可以開始了!");
                }
            }).start();
        }
    }
}

輸出結果:

參考資料:

https://blog.csdn.net/qq_19431333/article/details/68940987

https://blog.csdn.net/panweiwei1994/article/details/78826072

http://www.importnew.com/15731.html

二、CyclicBarrier 2.1CyclicBarrier簡介

A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

簡單來說:CyclicBarrier允許一組線程互相等待,直到到達某個公共屏障點。叫做cyclic是因為當所有等待線程都被釋放以后,CyclicBarrier可以被重用(對比于CountDownLatch是不能重用的)

使用說明:

CountDownLatch注重的是等待其他線程完成,CyclicBarrier注重的是:當線程到達某個狀態后,暫停下來等待其他線程,所有線程均到達以后,繼續執行。

2.2CyclicBarrier例子

例子:3y和女朋友約了去廣州夜上海吃東西,由于3y和3y女朋友住的地方不同,自然去的路徑也就不一樣了。于是他倆約定在體育西路地鐵站集合,約定等到相互見面的時候就發一條朋友圈。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Test {

    public static void main(String[] args) {

        final CyclicBarrier CyclicBarrier = new CyclicBarrier(2);
        for (int i = 0; i < 2; i++) {

            new Thread(() -> {

                String name = Thread.currentThread().getName();
                if (name.equals("Thread-0")) {
                    name = "3y";
                } else {
                    name = "女朋友";
                }
                System.out.println(name + "到了體育西");
                try {

                    // 兩個人都要到體育西才能發朋友圈
                    CyclicBarrier.await();
                    // 他倆到達了體育西,看見了對方發了一條朋友圈:
                    System.out.println("跟" + name + "去夜上海吃東西~");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

測試結果:

玩了一天以后,各自回到家里,3y和女朋友約定各自洗澡完之后再聊天

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Test {

    public static void main(String[] args) {

        final CyclicBarrier CyclicBarrier = new CyclicBarrier(2);
        for (int i = 0; i < 2; i++) {

            new Thread(() -> {

                String name = Thread.currentThread().getName();
                if (name.equals("Thread-0")) {
                    name = "3y";
                } else {
                    name = "女朋友";
                }
                System.out.println(name + "到了體育西");
                try {

                    // 兩個人都要到體育西才能發朋友圈
                    CyclicBarrier.await();
                    // 他倆到達了體育西,看見了對方發了一條朋友圈:
                    System.out.println("跟" + name + "去夜上海吃東西~");

                    // 回家
                    CyclicBarrier.await();
                    System.out.println(name + "洗澡");

                    // 洗澡完之后一起聊天
                    CyclicBarrier.await();

                    System.out.println("一起聊天");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

測試結果:

參考資料:

https://blog.csdn.net/panweiwei1994/article/details/78827000

三、Semaphore 3.1Semaphore簡介
Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource.

A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each {@link #acquire} blocks if necessary until a permit is available, and then takes it. Each {@link #release} adds a permit,potentially releasing a blocking acquirer.However, no actual permit objects are used; the {@code Semaphore} just

keeps a count of the number available and acts accordingly.

Semaphore(信號量)實際上就是可以控制同時訪問的線程個數,它維護了一組"許可證"

當調用acquire()方法時,會消費一個許可證。如果沒有許可證了,會阻塞起來

當調用release()方法時,會添加一個許可證。

這些"許可證"的個數其實就是一個count變量罷了~

3.2Semaphore例子

3y女朋友開了一間賣酸奶的小店,小店一次只能容納5個顧客挑選購買,超過5個就需要排隊啦~~~


import java.util.concurrent.Semaphore;

public class Test {

    public static void main(String[] args) {

        // 假設有50個同時來到酸奶店門口
        int nums = 50;

        // 酸奶店只能容納10個人同時挑選酸奶
        Semaphore semaphore = new Semaphore(10);

        for (int i = 0; i < nums; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    // 有"號"的才能進酸奶店挑選購買
                    semaphore.acquire();

                    System.out.println("顧客" + finalI + "在挑選商品,購買...");

                    // 假設挑選了xx長時間,購買了
                    Thread.sleep(1000);

                    // 歸還一個許可,后邊的就可以進來購買了
                    System.out.println("顧客" + finalI + "購買完畢了...");
                    semaphore.release();



                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

        }

    }
}

輸出結果:

反正每次只能5個客戶同時進酸奶小店購買挑選。

參考資料:

https://blog.csdn.net/qq_19431333/article/details/70212663

https://blog.csdn.net/panweiwei1994/article/details/78827248

四、總結

Java為我們提供了三個同步工具類

CountDownLatch(閉鎖)

某個線程等待其他線程執行完畢后,它才執行(其他線程等待某個線程執行完畢后,它才執行)

CyclicBarrier(柵欄)

一組線程互相等待至某個狀態,這組線程再同時執行。

Semaphore(信號量)

控制一組線程同時執行

本文簡單的介紹了一下這三個同步工具類是干嘛用的,要深入還得看源碼或者借鑒其他的資料。

最后補充一下之前的思維導圖知識點:

參考資料:

《Java并發編程實戰》

http://www.cnblogs.com/dolphin0520/p/3920397.html

https://zhuanlan.zhihu.com/p/27829595

如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y。為了大家方便,剛新建了一下qq群:742919422,大家也可以去交流交流。謝謝支持了!希望能多介紹給其他有需要的朋友

文章的目錄導航

https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76517.html

相關文章

  • Java】幾道讓你拿offer面試題

    摘要:的方法,的默認實現會判斷是否是類型注意自動拆箱,自動裝箱問題。適應自旋鎖鎖競爭是下的,會經過用戶態到內核態的切換,是比較花時間的。在中引入了自適應的自旋鎖,說明自旋的時間不固定,要不要自旋變得越來越聰明。 前言 只有光頭才能變強 之前在刷博客的時候,發現一些寫得比較好的博客都會默默收藏起來。最近在查閱補漏,有的知識點比較重要的,但是在之前的博客中還沒有寫到,于是趁著閑整理一下。 文本的...

    張春雷 評論0 收藏0
  • 老軟件問題種種

    摘要:基于的軟件系統部署時分層為應用包包啟動腳本包這就是基線,三個環境中的分層,任何一層在發布上線過程中的不一致都會導致潛在的問題。人們發明了各種工具進行排包,判斷,目前仍無法完全確保這種情況的萬無一失。 一個軟件數據活的一定比應用長,應用活的可能比維護的人長 有年頭的老應用,通常最早的設計者已經不在了。 最初關注點,業務域的約束,以及為什么在這里是這么設計的信息都沒有了。通常除了原創者,接...

    bbbbbb 評論0 收藏0
  • 軟件測試需要學什么?50W+測試工程師需要掌握哪些技能?

    摘要:協議學習常見請求方法學習和學習接口的基本概念接口文檔認識接口測試用例編寫接口測試工具使用軟件測試自動化進階性能測試性能測試的技術要求很高,不僅僅要對性能測試的指標測試分類測試設計有很深刻的理解。 ...

    wushuiyong 評論0 收藏0
  • 后端知識拓展 - 收藏集 - 掘金

    摘要:阻塞,非阻塞首先,阻塞這個詞來自操作系統的線程進程的狀態模型網絡爬蟲基本原理一后端掘金網絡爬蟲是捜索引擎抓取系統的重要組成部分。每門主要編程語言現未來已到后端掘金使用和在相同環境各加載多張小圖片,性能相差一倍。 2016 年度小結(服務器端方向)| 掘金技術征文 - 后端 - 掘金今年年初我花了三個月的業余時間用 Laravel 開發了一個項目,在此之前,除了去年換工作準備面試時,我并...

    CoderBear 評論0 收藏0
  • 后端知識拓展 - 收藏集 - 掘金

    摘要:阻塞,非阻塞首先,阻塞這個詞來自操作系統的線程進程的狀態模型網絡爬蟲基本原理一后端掘金網絡爬蟲是捜索引擎抓取系統的重要組成部分。每門主要編程語言現未來已到后端掘金使用和在相同環境各加載多張小圖片,性能相差一倍。 2016 年度小結(服務器端方向)| 掘金技術征文 - 后端 - 掘金今年年初我花了三個月的業余時間用 Laravel 開發了一個項目,在此之前,除了去年換工作準備面試時,我并...

    Carl 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<