成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

pingink / 2136人閱讀

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

前言

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

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

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()使計數(shù)器count減1。當count減到0時,所有在等待的線程均會被釋放

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

1.2CountDownLatch例子

例子:3y現(xiàn)在去做實習生了,其他的員工還沒下班,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("現(xiàn)在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現(xiàn)在負責倉庫模塊功能,但是能力太差了,寫得很慢,別的員工都需要等3y寫好了才能繼續(xù)往下寫。

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注重的是:當線程到達某個狀態(tài)后,暫停下來等待其他線程,所有線程均到達以后,繼續(xù)執(zhí)行。

2.2CyclicBarrier例子

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

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 {

                    // 兩個人都要到體育西才能發(fā)朋友圈
                    CyclicBarrier.await();
                    // 他倆到達了體育西,看見了對方發(fā)了一條朋友圈:
                    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 {

                    // 兩個人都要到體育西才能發(fā)朋友圈
                    CyclicBarrier.await();
                    // 他倆到達了體育西,看見了對方發(fā)了一條朋友圈:
                    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(信號量)實際上就是可以控制同時訪問的線程個數(shù),它維護了一組"許可證"。

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

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

這些"許可證"的個數(shù)其實就是一個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(閉鎖)

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

CyclicBarrier(柵欄)

一組線程互相等待至某個狀態(tài),這組線程再同時執(zhí)行。

Semaphore(信號量)

控制一組線程同時執(zhí)行。

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

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

參考資料:

《Java并發(fā)編程實戰(zhàn)》

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

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

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

相關文章

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

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

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

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

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

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

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

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

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

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

    CoderBear 評論0 收藏0

發(fā)表評論

0條評論

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