• 多线程-闭锁CountDownLatch


      闭锁相当于相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关着的,所有的线程都不可以通过。它可以使一个或者一组线程等待某个时间发生。闭锁状态包括一个计数器,初始化的时候传入一个正数,这个数字表示等待的事件的个数。countDown方法递减计数器,表示一个事件已经发生。如果计数器的值为非0,await方法会一直阻塞到计数器为0。当计数器为0,表示等待的事件已经发生,这时候所有的线程才可以继续往下执行。

      闭锁的实现有CountDownLatch,类似于我们生活的田径比赛,当运动员听到裁判员的哨声时,运动员才可以开始跑,未听到裁判的哨声运动员不可以跑。这个时候不管所有的运动员是否已经准备就绪了,只要哨声一响,就可以跑。这个跟后面的栅栏有区别,运动员只等待一个事件,就是听到裁判员的哨声响起。下面看一下实现的代码,如下:

    package countDownLatch.countDownLatch;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class CountDownLatchDemo {
    
        public static void main(String[]args) throws InterruptedException{
            final CountDownLatch startGate=new CountDownLatch(1);
            final CountDownLatch endGate=new CountDownLatch(5);
            //线程池
            ExecutorService exce=Executors.newCachedThreadPool();
            //创建5个线程
            for(int i=1;i<=5;i++){
                final int num=i;
                Thread thread =new Thread(new Runnable() {
                    public void run() {
                        try {
                            System.out.println(num+"号选手准备就绪,等待裁判员哨声响起..");
                            //相当于同步锁Synchronized中的await()方法
                            startGate.await();
                            try {
                                Thread.sleep((long) (Math.random()*10000));
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println(num+"号选手到达终点..");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        finally{
                            //相当于同步锁Synchronized中的notify()方法,区别在于countDown需要执行5次后才能唤醒await()
                            endGate.countDown();
                        }
                    }
                });
                exce.execute(thread);
            }
            long start=System.nanoTime();
            System.out.println("裁判员哨声响起..");
            Thread.sleep(10000);
            //唤醒执行startGate.await()的线程,让线程往下执行
            startGate.countDown();
            //等待被唤醒,主程序才能继续往下执行,线程中每次执行endGate.countDown()就减1,当为零的时候,主程序往下执行
            endGate.await();
            long end=System.nanoTime();
            System.out.println("所有运动员到达终点,耗时:"+(end-start));
            //关闭线程池
            exce.shutdown();
        }
    }

      执行结果如下:

      

       参考地址:JAVA并发编程实战

            http://m.jb51.net/article/63973.htm

  • 相关阅读:
    jQuery弹出层插件大全:
    JavaScript数组去重的几种方法
    sql去除重复列(行)
    VS无法启动调试
    .将DayOfWeek转换成中文的几种方式
    关于 uniqueidentifier
    链接服务器
    我的目标:系统架构师
    异常(1)
    Visual C++开发工具与调试技巧整理
  • 原文地址:https://www.cnblogs.com/gdpuzxs/p/6993260.html
Copyright © 2020-2023  润新知