JUC併發程式設計之Semaphore、CountDownLatch、CyclicBarrier協同工具

ldcaws發表於2020-10-10

Semaphore是一個計數訊號量,常用於限制可以訪問某些資源的執行緒數量,即一種用來控制併發量的共享鎖。
CountDownLatch是一個倒計數器,起跑訊號。
CyclicBarrier是一個迴圈柵欄,排隊摩天輪。
程式碼示例:
下面分別是三種併發協同工具的使用測試

public class SemaphoreDemo {
    static Semaphore sp = new Semaphore(6);
//    static KaneSemaphore sp = new KaneSemaphore(6);

    public static void main(String[] args) {
        for (int i = 0; i < 12; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        sp.acquire();//獲取訊號量
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println("當前訊號量限制...");
                    try {
                        Thread.sleep(2000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("執行完了");
                    sp.release();
                }
            }).start();
        }
    }
}

執行結果:

當前訊號量限制...
當前訊號量限制...
當前訊號量限制...
當前訊號量限制...
當前訊號量限制...
當前訊號量限制...
執行完了
當前訊號量限制...
執行完了
執行完了
執行完了
當前訊號量限制...
當前訊號量限制...
當前訊號量限制...
執行完了
執行完了
當前訊號量限制...
當前訊號量限制...
執行完了
執行完了
執行完了
執行完了
執行完了
執行完了
66個執行
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(6);
//        KaneCountDownLatch latch = new KaneCountDownLatch(6);

        //一種方式
        for (int i = 0; i < 6; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("開始準備...");
                    latch.countDown();//計數減一
                }
            }).start();
            Thread.sleep(1000L);
        }
        latch.await();//每個執行緒執行一次則-1,當lache為0時開始向下執行,就是這些現場都準備就緒,然後一起去幹同一件事

//        //另一種方式
//        for (int i = 0; i < 6; i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    latch.countDown();
//                    try {
//                        latch.await();
//                        System.out.println("執行緒:" + Thread.currentThread().getName() + "執行完畢");
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }).start();
//        }

        System.out.println("開始幹活...");
    }
}

執行結果

開始準備...
開始準備...
開始準備...
開始準備...
開始準備...
開始準備...
開始幹活...

public class CyclicBarrierDemo {

    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(4);
//        KaneCyclicBarrier barrier = new KaneCyclicBarrier(4);

        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
//                    barrier.await();
                    try {
                        barrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println("任務開始執行");
                }
            }).start();
            Thread.sleep(500L);
        }
    }
}

執行結果

任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
任務開始執行
...
44個執行

相關文章