Java多線程編程七 同步計(jì)數(shù)器

線程同步計(jì)數(shù)器

利用線程池進(jìn)行線程開發(fā)使用時(shí),因join方法使用不便而引入了線程同步計(jì)數(shù)器。

CountDownLatch計(jì)數(shù)器

通過代理變量sync 實(shí)現(xiàn)AbstractQueuedSynchronizer接口。

CountDownLatch是通過一個(gè)計(jì)數(shù)器來實(shí)現(xiàn)的,計(jì)數(shù)器的初始值為線程的數(shù)量。每當(dāng)一個(gè)線程完成了自己的任務(wù)后,計(jì)數(shù)器的值就會(huì)減1,當(dāng)計(jì)數(shù)器值到達(dá)0時(shí),它表示所有的線程已經(jīng)完成了任務(wù),然后在閉鎖上等待的線程就可以恢復(fù)執(zhí)行任務(wù)。

CountDownLatch中主要方法如下:

public CountDownLatch(int count);//,構(gòu)造函數(shù)中的count(計(jì)數(shù)器)實(shí)際上就是閉鎖需要等待的線程數(shù)量,這個(gè)值只能被設(shè)置一次,而且CountDownLatch沒有提供任何機(jī)制去重新設(shè)置這個(gè)計(jì)數(shù)值。

public void countDown();//每調(diào)用一次這個(gè)方法,在構(gòu)造函數(shù)中初始化的count值就減1,通知機(jī)制是此方法來完成的。

public void await() throws InterruptedException//調(diào)用此方法的當(dāng)前線程會(huì)一直阻塞,直到計(jì)時(shí)器的值為0。

簡(jiǎn)單使用

public static void main(String[] args) throws InterruptedException {
    CountDownLatch countDownLatch = new CountDownLatch(11);
    ExecutorService service = Executors.newFixedThreadPool(7);
    int i =1;
    Runnable runnable = ()->{
        System.out.println("countDownLatch前"+Thread.currentThread().getName());
        countDownLatch.countDown();
        /*try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        System.out.println("countDownLatch后"+Thread.currentThread().getName());

    };

    for(int j = 0; j < 10;j++)
        service.execute(runnable);


    countDownLatch.await();
    System.out.println("hello"+countDownLatch.getCount());
    service.shutdown();
}

CyclicBarrier回環(huán)屏障

通過代理的獨(dú)占鎖實(shí)現(xiàn)

public CyclicBarrier(int parties);
public CyclicBarrier(int parties, Runnable barrierAction);

public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
  • 線程調(diào)用 await() 表示自己已經(jīng)到達(dá)柵欄

  • BrokenBarrierException 表示柵欄已經(jīng)被破壞,破壞的原因可能是其中一個(gè)線程 await() 時(shí)被中斷或者超時(shí)

  • 所有線程會(huì)等待全部線程到達(dá)柵欄之后才會(huì)繼續(xù)執(zhí)行,并且最后到達(dá)的線程會(huì)完成 Runnable 的任務(wù)。

CyclicBarrier和CountDownLatch的區(qū)別
CountDownLatch的計(jì)數(shù)器只能使用一次,而CyclicBarrier的計(jì)數(shù)器可以使用reset()方法重置,可以使用多次,所以CyclicBarrier能夠處理更為復(fù)雜的場(chǎng)景;

CyclicBarrier還提供了一些其他有用的方法,比如getNumberWaiting()方法可以獲得CyclicBarrier阻塞的線程數(shù)量,isBroken()方法用來了解阻塞的線程是否被中斷;

CountDownLatch允許一個(gè)或多個(gè)線程等待一組事件的產(chǎn)生,而CyclicBarrier用于等待其他線程運(yùn)行到柵欄位置。

Semaphore信號(hào)量

通過代理變量sync 實(shí)現(xiàn)AbstractQueuedSynchronizer接口。

Semaphore 是一個(gè)計(jì)數(shù)信號(hào)量,必須由獲取它的線程釋放。

常用于限制可以訪問某些資源的線程數(shù)量,例如通過 Semaphore 限流。

Semaphore 只有3個(gè)操作:初始化 增加 減少

Semaphore(int permits);//構(gòu)造方法,創(chuàng)建具有給定許可數(shù)的計(jì)數(shù)信號(hào)量并設(shè)置為非公平信號(hào)量。

Semaphore(int permits,boolean fair);//構(gòu)造方法,當(dāng)fair等于true時(shí),創(chuàng)建具有給定許可數(shù)的計(jì)數(shù)信號(hào)量并設(shè)置為公平信號(hào)量。

void acquire();//從此信號(hào)量獲取一個(gè)許可前線程將一直阻塞。相當(dāng)于一輛車占了一個(gè)車位。

void acquire(int n);//從此信號(hào)量獲取給定數(shù)目許可,在提供這些許可前一直將線程阻塞。比如n=2,就相當(dāng)于一輛車占了兩個(gè)車位。

void release();//釋放一個(gè)許可,將其返回給信號(hào)量。就如同車開走返回一個(gè)車位。

void release(int n);//釋放n個(gè)許可。

int availablePermits();//當(dāng)前可用的許可數(shù)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容