java併發編程中必須學會的三個常用的輔助類(CountDownLatch,CyclicBarrier,Semaphore)

1. CountDownLatch
在這裏插入圖片描述
CountDownLatch用給定的計數初始化。 [await]方法阻塞,直到由於countDown()方法的[調用]而導致當前計數達到零,之後所有等待線程被釋放,並且任何後續的await [調用立即]返回。 這是一個一次性的現象 - 計數無法重置。 如果您需要重置計數的版本,請考慮使用[CyclicBarrier] 。

package com.add;

import java.util.concurrent.CountDownLatch;

//計數器
public class CountDownLatchDemo01 {
    public static void main(String[] args) throws InterruptedException {
        //總數是6,類似於倒計時.參數設置爲6,即等待6個線程執行完畢
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"GO OUT");
                countDownLatch.countDown();//-1
            },String.valueOf(i)).start();
        }
        countDownLatch.await();//等待計數器歸零,然後在向下執行

​        System.out.println("close door");}
}

原理:

//總數是6,類似於倒計時.參數設置爲6,即等待6個線程執行完畢
CountDownLatch countDownLatch = new CountDownLatch(6);
countDownLatch.countDown();//-1

countDownLatch.await();//等待計數器歸零,然後在向下執行

每次有線程調用countDown()數量減一假如計數器變爲0,countDownLatch.await()就會被喚醒,繼續執行!
2.CyclicBarrier
在這裏插入圖片描述

package com.add;

import com.sun.org.apache.xerces.internal.xs.ItemPSVI;

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

/**

 * 集齊七龍珠召喚神龍

 * 召喚控住的線程
   */
   public class CyclicBarrierDemo02 {
   public static void main(String[] args) {
       CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
           System.out.println("召喚神龍成功!"); });
       for (int i = 0; i < 7; i++) {
           final int temp = i;
           new  Thread(()->{
              // cyclicBarrier.getParties(); 由於數組自動遞增,這裏可以不設置
               System.out.println(Thread.currentThread().getName()+"收集了第"+temp+"顆龍珠");try {
   ​                cyclicBarrier.await();} catch (InterruptedException e) {
   ​                e.printStackTrace();} catch (BrokenBarrierException e) {
   ​                e.printStackTrace();}}).start();}
   }
   }

3. Semaphore
semaphore:信號量
在這裏插入圖片描述
代碼:

package com.add;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo03 {
    public static void main(String[] args) {
        //限流的時候,會用到
        Semaphore semaphore = new Semaphore(5, true);
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                //acquire()都會阻塞(得到許可證),release()添加許可證,潛在地釋放阻塞獲取方(釋放)
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"搶到車位");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+"離開了車位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

原理: acquire()獲得,假設如果已經滿了,等待被釋放爲止
release()釋放,會將當前的信號量釋放+1,然後喚醒等待的線程!
作用:多個共享資源互斥的使用!併發限流,控制最大的限流數.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章