JAVA多線程之CyclicBarrier 、CountDownLatch 、Semaphore的用法

1.CountDownLatch (線程計數器)

利用CountDownLatch 可以實現類似計數器的功能,比如主線程需要等待5個子線程執行完畢之後才能執行,就可以利用CountDownLatch實現,案例如下:

public class TestThread {
    final static CountDownLatch latch = new CountDownLatch(5); //如果大於num將會造成一直等待

    public static void main(String[] args) throws InterruptedException {
        //線程數
        int num = 5;
        MyRunnable myRunnable = new MyRunnable();

        for(int i=0;i<5;i++){
            new Thread(myRunnable).start();
        }
        latch.await();
        System.out.println("主線程了");
    }
}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"我是run方法");
        TestThread.latch.countDown();
    }
}

執行結果:

2.CyclicBarrier(迴環柵欄)

迴環柵欄的作用就是整合一組線程,在這一組線程全部達到某個狀態之後同時執行,其最重要的方法爲await()

1.  public int await():用來掛起當前線程,直至所有線程都到達 barrier 狀態再同時執行後續任
務;
2.  public int await(long timeout, TimeUnit unit):讓這些線程等待至一定的時間,如果還有
線程沒有到達 barrier 狀態就直接讓到達 barrier 的線程執行後續任務。

案例:

public class TestThread {
    public static void main(String[] args) throws InterruptedException {
        //線程數
        int num = 5;
        CyclicBarrier cb = new CyclicBarrier(5);    //如果大於num將會造成一直等待
        MyRunnable myRunnable = new MyRunnable(cb);

        for(int i=0;i<num;i++){
            new Thread(myRunnable).start();
        }
    }
}

class MyRunnable implements Runnable{

    private CyclicBarrier cb;

    public MyRunnable(){}

    public MyRunnable(CyclicBarrier cb){
        this.cb = cb;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            System.out.println("業務代碼操作完成,等待其他線程執行完畢");
            cb.await();
            System.out.println("所有線程執行完畢");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

執行結果:

3.Semaphore(信號量)

Semaphore可以控制同時訪問的線程個數,通過acquire() 獲取一個許可,如果沒有就等待,而 release() 釋放一個許可。

案例:

public class TestThread {
    final static int S_NUM = 1;
    final static Semaphore SP = new Semaphore(S_NUM);

    public static void main(String[] args) throws InterruptedException {
        //線程數
        int num = 5;
        MyRunnable myRunnable = new MyRunnable();

        for(int i=0;i<num;i++){
            new Thread(myRunnable).start();
        }
    }
}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        try {
            TestThread.SP.acquire();
            System.out.println(Thread.currentThread().getName()+"在執行start");
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName()+"在執行end");
            TestThread.SP.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

執行結果(S_NUM=1時):

執行結果(S_NUM=2時):

由S_NUM=2可以看出Semaphore可以控制線程同時執行數量。

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