1. 程式人生 > >java 併發包同步 CountDownLatch, CyclicBarrier, Semaphore

java 併發包同步 CountDownLatch, CyclicBarrier, Semaphore

java 執行緒併發包

  • 通常為java.util.concurrent 下的包

執行緒包提供的同步結構主要有三個

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
CountDownLatch
  • CountDownLatch 允許一個執行緒或多個執行緒等待某些操作完成,一般用於等待事件的促發
  • 例項:
/**
 * @Author: gsonp
 * @Date: 2018/10/10 20:42
 */
public class CountDownLatchTest {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch=new CountDownLatch(1);

        Thread a=new Thread(new RunnerA(countDownLatch));
        a.start();


        Thread b=new Thread(new RunnerB(countDownLatch));
        b.start();

    }
    public static class RunnerA implements Runnable{
        CountDownLatch countDownLatch;

        public RunnerA(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            System.out.println("阻塞 等待B執行完成");
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {

            }
            System.out.println("B執行緒執行完成");
        }
    }


    public static class RunnerB implements Runnable{
        CountDownLatch countDownLatch;

        public RunnerB(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
              
            }
            System.out.println("喚醒A 執行緒");
            countDownLatch.countDown();
        }
    }
}

執行結果:

阻塞B等待執行完成
喚醒A 執行緒
B執行緒執行完成
  • CountDownLatch 缺點: CountDownLatch 計數器只有在物件建立的時候被初始化,變為0的時候,就無法再次使用
CyclicBarrier
  • CyclicBarier 允許多個執行緒到達一個屏障,執行緒阻塞 當最後一個執行緒到達屏障時,屏障開啟,所有執行緒繼續執行。一般用於在多執行緒計算中,多個執行緒計算完成,主執行緒統計結果
  • 例項:
public class CyclicBarrierTest {
    public static void main(String[] args){
        CyclicBarrier cb=new CyclicBarrier(2);
        Thread a=new Thread(new RunnerA(cb));
        a.start();

        Thread b=new Thread(new RunnerB(cb));
        b.start();
    }

    public static class RunnerA implements Runnable{
        CyclicBarrier cb;
        public RunnerA(CyclicBarrier cb) {
            this.cb = cb;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(2000);
                System.out.println("A執行到達屏障,等待B執行完成");
                cb.await();
                System.out.println("B執行完成,A繼續執行");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static class RunnerB implements Runnable{
        CyclicBarrier cb;
        public RunnerB(CyclicBarrier cb) {
            this.cb = cb;
        }
        @Override
        public void run() {
            try {
                Thread.sleep(3000);
                System.out.println("B執行到達屏障");
                cb.await();
                System.out.println("B繼續執行");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

當CyclicBarrier 屏障開啟後,會自動重置,不需要收到呼叫reset方法

Semaphore
  • Semaphore java 版本的訊號量,設定permit ,限制對通用資源訪問的目的,一般用於對資源訪問的控制
  • 例項:
/**
 * @Author: gsonp
 * @Date: 2018/10/11 20:19
 */
public class SemaphoreTest {
    public static void main(String[] args){
        Semaphore sp=new Semaphore(1);
        Thread a=new Thread(new RunnerA(sp));
        a.start();

        Thread b=new Thread(new RunnerB(sp));
        b.start();
    }

    public static class RunnerA implements Runnable{
        Semaphore sp;
        public RunnerA(Semaphore sp) {
            this.sp = sp;
        }

        @Override
        public void run() {
            try {
                System.out.println("A執行獲取permit");
                sp.acquire();
                Thread.sleep(4000);
                sp.release();
                System.out.println("A執行完成,釋放permit");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static class RunnerB implements Runnable{
        Semaphore sp;
        public RunnerB(Semaphore sp) {
            this.sp = sp;
        }
        @Override
        public void run() {
            try {
                System.out.println("B執行等待獲取permit");
                sp.acquire();
                System.out.println("B執行完畢是否permit");
                sp.release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Semaphore 一般用於對資源的訪問做限制