java同步工具的使用

一阅酪、Semaphore

(1)示例

package com.suncy.article.article8;

import lombok.SneakyThrows;

import java.util.concurrent.Semaphore;

public class SyncToolsDemo1 {
    public static void main(String[] args) {
        //1旨袒、Semaphore并發(fā)數(shù)的限制
        //定義了可以訪問資源的線程數(shù)量
        Semaphore semaphore = new Semaphore(2);
        for (int i = 0; i < 4; i++) {
            int finalI = i;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    //獲取請求許可
                    semaphore.acquire();
                    System.out.println(finalI);
                    Thread.sleep(1000);
                    //釋放許可
                    semaphore.release();
                }
            }).start();
        }
    }
}

(2)結(jié)果

image.png

(3)結(jié)果說明

打印是先打印0、1遮斥,1秒之后打印2峦失、3。因為設(shè)置的資源并發(fā)訪問數(shù)是2术吗,所以同時只有兩個線程可以訪問資源。

二帆精、CountDownLatch和CyclicBarrier的使用

(1)示例

package com.suncy.article.article8;

import lombok.SneakyThrows;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class SyncToolsDemo2 {
    public static void main(String[] args) throws InterruptedException {
        //2较屿、調(diào)用await的線程 需要等待countDownLatch為0后才能繼續(xù)執(zhí)行 不可重復(fù)使用
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            int finalI = i + 1;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    Thread.sleep(finalI * 1000);
                    System.out.println("準(zhǔn)備第" + finalI + "份食材");
                    countDownLatch.countDown();
                }
            }).start();
        }

        // 主線程等待檢查
        countDownLatch.await();
        System.out.println("食材準(zhǔn)備好了,廚師開始做飯");

        //CyclicBarrier 可重復(fù)使用 調(diào)用await的線程阻塞卓练,等待cyclicBarrier為0后繼續(xù)執(zhí)行后續(xù)操作
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
        for (int i = 0; i < 4; i++) {
            int finalI = i + 1;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    Thread.sleep(finalI * 1000);
                    System.out.println("第" + finalI + "個人已經(jīng)到了隘蝎,等待其他人到");
                    cyclicBarrier.await();

                    System.out.println("人都到齊了," + finalI + "開始吃飯了");
                    Thread.sleep(finalI * 1000);
                    System.out.println("第" + finalI + "吃完飯了,坐到了麻將桌襟企,等待其他人吃完飯");

                    cyclicBarrier.await();
                    System.out.println("人都到齊了," + finalI + "開始打麻將");
                }
            }).start();
        }
    }
}

(2)結(jié)果

image.png

(3)結(jié)果說明

CountDownLatch一般用于:主線程等待其他線程都執(zhí)行完后嘱么,再進(jìn)行后續(xù)操作。
CyclicBarrier一般用于:其他線程相互等待顽悼,直到達(dá)到了要求的線程數(shù)之后曼振,再進(jìn)行后續(xù)操作。

三蔚龙、Phaser實現(xiàn)CountDownLatch和CyclicBarrier 相同的功能

(1)示例

package com.suncy.article.article8;

import lombok.SneakyThrows;

import java.util.concurrent.Phaser;

public class SyncToolsDemo3 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("設(shè)置phase為5");
        Phaser phaser = new Phaser(5);
        System.out.println("打印初始化之后的phase序列號:" + phaser.getPhase());
        System.out.println("打印phaser注冊的值:" + phaser.getRegisteredParties());

        for (int i = 0; i < 5; i++) {
            final int finalI = i + 1;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    Thread.sleep(finalI * 1000);
                    System.out.println("第" + finalI + "個線程執(zhí)行任務(wù)");
                    if (finalI == 5) {
                        System.out.println("第" + finalI + "個線程執(zhí)行完畢冰评,下次不再參與,此時減少phaser量");
                        phaser.arriveAndDeregister();
                    } else {
                        phaser.arrive();
                    }
                }
            }).start();
        }

        //等待第一輪阻塞的所有節(jié)點都到達(dá)
        phaser.awaitAdvance(0);
        System.out.println("第1輪同步完之后木羹,打印phase序列號" + phaser.getPhase());
        System.out.println("打印phaser注冊的值:" + phaser.getRegisteredParties());
        for (int i = 0; i < 4; i++) {
            int finalI = i + 1;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    System.out.println("第" + finalI + "個線程正在執(zhí)行任務(wù)");
                    phaser.arriveAndAwaitAdvance();
                }
            }).start();

        }
        phaser.awaitAdvance(1);
        System.out.println("第2輪同步完之后甲雅,打印phase序列號" + phaser.getPhase());
        System.out.println("給phaser新增一個");
        phaser.register();
        System.out.println("phaser新增一個之后的值:" + phaser.getRegisteredParties());
        for (int i = 0; i < 5; i++) {
            int finalI = i + 1;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    phaser.arriveAndAwaitAdvance();
                }
            }).start();

        }
        System.out.println("打印phase序列號:" + phaser.getPhase());
        phaser.awaitAdvance(2);
        System.out.println("第3輪同步完之后,打印phase序列號" + phaser.getPhase());
    }
}

(2)結(jié)果

image.png

(3)結(jié)果說明

getPhase() :拿到周期數(shù)坑填,初始化之后周期數(shù)為0抛人,每輪周期完成之后,會自動加1脐瑰。

arriveAndDeregister():到達(dá)屏障妖枚,并減少屏障數(shù)。

arrive():到達(dá)屏障蚪黑,繼續(xù)執(zhí)行盅惜,不阻塞中剩。

arriveAndAwaitAdvance():到達(dá)屏障,阻塞抒寂,等待其他線程结啼。

register():新增一個屏障。

awaitAdvance(1):根據(jù)周期數(shù)屈芜,判斷當(dāng)前是否需要阻塞郊愧。如果當(dāng)前的周期數(shù)和參數(shù)的值相同,則阻塞等待井佑,否則會繼續(xù)執(zhí)行属铁。

四、Exchanger

(1)示例

package com.suncy.article.article8;

import lombok.SneakyThrows;

import java.util.concurrent.Exchanger;

public class SyncToolsDemo4 {
    public static void main(String[] args) throws InterruptedException {
        Exchanger<String> exchanger = new Exchanger<String>();
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                String exchange = exchanger.exchange("一瓶飲料");
                System.out.println("朋友小花用飲料換到了[" + exchange + "]");
            }
        }).start();
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                String exchange = exchanger.exchange("2塊錢");
                System.out.println("小明用2塊錢換到了[" + exchange + "]");
            }
        }).start();
    }
}

(2)結(jié)果

image.png

(3)結(jié)果說明

用于兩個線程間的數(shù)據(jù)交換躬翁,盡量不要用于多個線程焦蘑,情況不可控。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盒发,一起剝皮案震驚了整個濱河市例嘱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宁舰,老刑警劉巖拼卵,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛮艰,居然都是意外死亡腋腮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門壤蚜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來即寡,“玉大人,你說我怎么就攤上這事仍律『傩” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵水泉,是天一觀的道長善涨。 經(jīng)常有香客問我,道長草则,這世上最難降的妖魔是什么钢拧? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮炕横,結(jié)果婚禮上源内,老公的妹妹穿的比我還像新娘。我一直安慰自己份殿,他們只是感情好膜钓,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布嗽交。 她就那樣靜靜地躺著,像睡著了一般颂斜。 火紅的嫁衣襯著肌膚如雪夫壁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天沃疮,我揣著相機與錄音盒让,去河邊找鬼。 笑死司蔬,一個胖子當(dāng)著我的面吹牛邑茄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俊啼,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肺缕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吨些?” 一聲冷哼從身側(cè)響起搓谆,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豪墅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黔寇,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡偶器,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缝裤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屏轰。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖憋飞,靈堂內(nèi)的尸體忽然破棺而出霎苗,到底是詐尸還是另有隱情,我是刑警寧澤榛做,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布唁盏,位于F島的核電站,受9級特大地震影響检眯,放射性物質(zhì)發(fā)生泄漏厘擂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一锰瘸、第九天 我趴在偏房一處隱蔽的房頂上張望刽严。 院中可真熱鬧,春花似錦避凝、人聲如沸舞萄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倒脓。三九已至撑螺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間把还,已是汗流浹背实蓬。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吊履,地道東北人安皱。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像艇炎,于是被迫代替她去往敵國和親酌伊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容