JAVA多線程之——CyclicBarrier

CyclicBarrier

CyclicBarrier : N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。
CountDownLatch是某一個線程等待一個或者N個線程。
主體不同,CountDownLatch的主體是某一個線程。它是要一個或者多個線程完成某一個動作之後自己執行。這些線程互相之間是不等待的。
CyclicBaarier 主體是N個線程,就是說大家在某一個點上互相等待。只有大家都到了這個點,大家才能各自做自己接下來的事情。
還是用導入例子還說:

public class CyclicBarrierTest {
    static CyclicBarrier  ct = new CyclicBarrier(3);

    public static void main(String[] args) throws InterruptedException {

         new Thread(new ImportExcel(), "t1").start(); 
         new Thread(new ImportExcel(), "t2").start();
         new Thread(new ImportExcel(), "t3").start();
         System.out.println("導入成功。。。。。。。");


    }

    static class ImportExcel implements Runnable{
        @Override
        public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() +"導入成功");
                        ct.await();
                        System.out.println(Thread.currentThread().getName() +"記錄日誌");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }

        }

    }
}

某次運行結果:

導入成功。。。。。。。
t3導入成功
t1導入成功
t2導入成功
t2記錄日誌
t3記錄日誌
t1記錄日誌

結果可以看到,首先主線程是不等待其它線程的。第二,無論怎麼運行,一定是t1,t2,t3都導入成功之後,才能大家各自做日誌記錄。這就是大家互相等待,一定要完成各自的任務才能接着做某事。當然它也能實現各自導入成功之後就通知用戶導入成功:

public class CyclicBarrierTest {
    static CyclicBarrier  ct = new CyclicBarrier(3,new  Runnable() {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() +"通知用戶導入成功");

        }
    });

    public static void main(String[] args) throws InterruptedException {

         new Thread(new ImportExcel(), "t1").start(); 
         new Thread(new ImportExcel(), "t2").start();
         new Thread(new ImportExcel(), "t3").start();


    }

    static class ImportExcel implements Runnable{
        @Override
        public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() +"導入成功");
                        ct.await();
                        System.out.println(Thread.currentThread().getName() +"記錄日誌");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }

        }

    }
}

只有導入成功之後,再通知用戶。使用另外一個構造函數 public CyclicBarrier(int parties, Runnable barrierAction)。這個構造函數是只有在所有線程到達某個點之後再執行後面的Runnable中的run方法。

發佈了61 篇原創文章 · 獲贊 23 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章