CyclierBarrier 和 CountDawnLatch

CountDawnLatch

用 CountDownLatch 控制多個線程同時開始

  • 思路: 通過主線程設置 CountDawnLatch 值爲 1,其他線程設置 await(),等待count=0, 主線程執行 count.countDown(),喚醒所有等待線程

/**
 * 用 CountDownLatch 控制多個線程同時開始
 * 思路: 通過主線程設置 CountDawnLatch 值爲 1,其他線程設置 await(),等待count=0, 主線程執行 count.countDown(),喚醒所有等待線程
 *
 */
public class CountDawnLatchDemo
{
    public static void main(String[] args) throws InterruptedException
    {
        CountDownLatch count = new CountDownLatch(1);
        
        new Thread(new Runnable() {
            @Override
            public void run()
            {
                try
                {
                    count.await();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                System.out.println("thread1 結束");
            }
        }).start();
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    count.await();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                count.countDown();
                System.out.println("thread2 結束");
            }
        }).start();
        
        Thread.sleep(3000);
        count.countDown();
        
    }
}

CyclicBarrier

*CyclicBarrier 控制多個線程同時開始

  • 思路:CyclicBarrier 設置柵欄解鎖條件爲 n,啓動n個線程,每個線程調用 await(), 直到第n個線程進入柵欄時,才解鎖喚醒所有線程
  • CyclicBarrier還可以設置解鎖後的新任務 , 會選擇其中一個線程去執行方法Runable(). 一般選擇最後一個進入柵欄的線程

/**
 * CyclicBarrier 控制多個線程同時開始
 * 思路:CyclicBarrier 設置柵欄解鎖條件爲 n,啓動n個線程,每個線程調用 await(), 直到第n個線程進入柵欄時,才解鎖喚醒所有線程
 * CyclicBarrier還可以設置解鎖後的新任務 , 會選擇其中一個線程去執行方法Runable(). 一般選擇最後一個進入柵欄的線程
 *
 */
public class CyclicBarrierDemo
{
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException
    {
        CyclicBarrier cb = new CyclicBarrier(3, new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println("被選擇處理 action的線程是: " + Thread.currentThread().getName());
                System.out.println("action after barrier ");
            }
        });
        
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    cb.await(); // 到達屏障,當前線程被阻塞,只有所有需要的線程數量到達屏障後,屏障纔會解除,執行
                }
                catch (InterruptedException | BrokenBarrierException e)
                {
                    e.printStackTrace();
                }
                System.out.println("thread 1 await over");
            }
        }, "thread1").start();
        
        Thread.sleep(3000);
        
        Thread t2 = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    cb.await();
                    Thread.sleep(7000);
                    System.out.println("當前阻塞的線程數:" + cb.getNumberWaiting());
                }
                catch (InterruptedException | BrokenBarrierException e)
                {
                    e.printStackTrace();
                }
                System.out.println("thread 2 await over");
            }
        }, "thread2");
        t2.start();
        
        Thread.sleep(1000);
        System.out.println("main: 當前阻塞的線程數:" + cb.getNumberWaiting());
        t2.interrupt(); // t2線程處於 await() 時被中斷,導致柵欄失效,所有正在柵欄處等待的線程拋出BrokenBarrier異常(t2拋出 中斷異常),執行後續的操作
        Thread.sleep(100);
        System.out.println("main: 當前阻塞的線程數:" + cb.getNumberWaiting());
        
        // 拋出  BrokenBarrierException 異常,終止程序
        cb.await();
        
        System.out.println("main over");
        
    }
    
}

public class CyclicBarrierDemo3
{
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException
    {
        CyclicBarrier cb = new CyclicBarrier(3);
        new Thread(new Runner(cb)).start();
        Thread.sleep(100);
        new Thread(new Runner(cb)).start();
        Thread.sleep(2100);
        System.out.println(cb.getNumberWaiting()); // 此時線程0 、1 都在處於 await()狀態 , 1s 後線程 0 檢測到超時,拋出 TimeoutException ,柵欄解除,線程 1 拋出 BrokenBarrierException
        
        Thread.sleep(4000);
        System.out.println(cb.getNumberWaiting());
        
        cb.await(); // main 線程拋出 BrokenBarrierException
        System.out.println("main over");
    }
    
    static class Runner implements Runnable
    {
        
        private CyclicBarrier cb;
        
        public Runner(CyclicBarrier cb)
        {
            this.cb = cb;
        }
        
        @Override
        public void run()
        {
            try
            {
                System.out.println(Thread.currentThread().getName() + "進入");
                Thread.sleep(2000);
                cb.await(1000, TimeUnit.MILLISECONDS);
            }
            
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            catch (BrokenBarrierException e)
            {
                System.out.println("線程" + Thread.currentThread().getName() + "拋出BrokenBarrierException");
                e.printStackTrace();
            }
            catch (TimeoutException e)
            {
                System.out.println("線程" + Thread.currentThread().getName() + "拋出TimeoutException");
                e.printStackTrace();
            }
            System.out.println("線程" + Thread.currentThread().getName() + " 執行任務");
            
        }
    }
}

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