java CyclicBarrier同步屏障

CyclicBarrier的字面意思是可循環使用的屏障,它的主要做用是,讓一組線程到達一個屏障時被阻塞,知道最後一個線程到達屏障時,屏障纔會打開,全部被屏障攔截的線程纔會繼續運行。java

一、簡介:ide

  CyclicBarrier默認的構造方法是CyclicBarrier(int parties),其中參數標識屏障攔截的線程數量,每一個線程調用await方法告訴CyclicBarrier我已經到達了屏障,而後當前線程被阻塞。函數

package com.test;

import java.util.concurrent.CyclicBarrier;

public class CiclicBarrierTest {
    
    static CyclicBarrier c = new CyclicBarrier(2);
    
    public static void main(String[] args) {
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(1);
            }
        }).start();
        
        try {
            c.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(2);
    }
}

若是把new CyclicBarrier(2)修改擦new CyclicBarrier(3) 則主線程和子線程會永遠等待,由於沒有第三個線程去執行await方法。既沒有第三個線程到達屏障,因此以前到達屏障的兩個線程都不會繼續執行。spa

 

CyclicBarrier還提供一個更高級的構造函數,CyclicBarrier(int parties, Runnable barrier-Action)用於在線程到達屏障時,優先執行barrierAction,方便處理更復雜的業務場景:線程

package com.test;

import java.util.concurrent.CyclicBarrier;

public class CiclicBarrierTest {
    
    static CyclicBarrier c = new CyclicBarrier(2, new A());
    
    public static void main(String[] args) {
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(1);
            }
        }).start();
        
        try {
            c.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(2);
    }
    
    public static class A implements Runnable {

        @Override
        public void run() {
            System.out.println(3);
        }
        
    }
}
// 結果
3
1
2

 

CyclicBarrier和CountDownLatch的區別:code

  CountDownLatch的計數器只能使用一次,而CyclicBarrier的計數器能夠使用reset()方法重置。因此CyclicBarrier能處理更爲複雜的業務場景。blog

  CyclicBarrier還提供其餘有用的方法,好比getNumberWaiting方法能夠得到被阻塞的線程數量. isBroken()方法用來了解阻塞的線程是否被中斷。get

相關文章
相關標籤/搜索