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() + " 执行任务");
            
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值