转自:

  http://www.cnblogs.com/dolphin0520/p/3920397.html

1.简介

  • CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。
  • CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行
  • CyclicBarrier 回环栅栏,一般用于一组线程互相等待至某个状态,然后这一组线程再同时开始执行后续任务
  • CountDownLatch 在使用完后不可重用
  • CyclicBarrier 使用完后可重用
  • Semaphore 信号量,一般用于控制对某组资源的访问权限。

2.CountDownLatch示例

    void testCountDownLatch() {
         final CountDownLatch latch = );
         new Thread() {
             public void run() {
                 try {
                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "正在执行");
                     Thread.sleep();
                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "执行完毕");
                     latch.countDown();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }

             ;
         }.start();

         new Thread() {
             public void run() {
                 try {
                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "正在执行");
                     Thread.sleep();
                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "执行完毕");
                     latch.countDown();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }

             ;
         }.start();

         try {
             Log.d(TAG, "等待2个子线程执行完毕...");
             latch.await();
             Log.d(TAG, "2个子线程已经执行完毕");
             Log.d(TAG, "继续执行主线程");
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }

3.CyclicBarrier示例

 static class Writer extends Thread {
         private CyclicBarrier cyclicBarrier;

         public Writer(CyclicBarrier cyclicBarrier) {
             this.cyclicBarrier = cyclicBarrier;
         }

         @Override
         public void run() {
             Log.d(TAG, "线程" + Thread.currentThread().getName() + "正在写入数据...");
             try {
                 Thread.sleep();      //以睡眠来模拟写入数据操作
                 Log.d(TAG, "线程" + Thread.currentThread().getName() + "写入数据完毕,等待其他线程写入完毕");
                 cyclicBarrier.await();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } catch (BrokenBarrierException e) {
                 e.printStackTrace();
             }
             Log.d(TAG, "所有线程写入完毕,继续处理其他任务...");
         }
     }

     //用来阻塞当前线程,直至所有线程都到达barrier状态再同时执行后续任务;
     void testCyclicBarrier1(){
         ;
         CyclicBarrier barrier = new CyclicBarrier(N);
         ; i < N; i++) {
             new Writer(barrier).start();
         }
     }

     //如果说想在所有线程写入操作完之后,进行额外的其他操作可以为CyclicBarrier提供Runnable参数
     void testCyclicBarrier2(){
         ;
         CyclicBarrier barrier = new CyclicBarrier(N, new Runnable() {
             @Override
             public void run() {
                 Log.d(TAG, "当前线程" + Thread.currentThread().getName());
             }
         });

         ; i < N; i++){
             new Writer(barrier).start();
         }
     }

     //CyclicBarrier是可以重用的
     void testCyclicBarrier3(){
         ;
         CyclicBarrier barrier = new CyclicBarrier(N);

         ; i < N; i++) {
             new Writer(barrier).start();
         }

         try {
             Thread.sleep();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }

         Log.d(TAG, "CyclicBarrier重用");

         ; i < N; i++) {
             new Writer(barrier).start();
         }
     }

     //故意让最后一个线程启动延迟,因为在前面三个线程都达到barrier之后,
     //等待了指定的时间发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务。
     void testCyclicBarrier4(){

         ;
         CyclicBarrier barrier = new CyclicBarrier(N);

         ; i < N; i++) {
             )
                 new Writer2(barrier).start();
             else {
                 try {
                     Thread.sleep();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 new Writer(barrier).start();
             }
         }
     }
     static class Writer2 extends Thread{
         private CyclicBarrier cyclicBarrier;
         public Writer2(CyclicBarrier cyclicBarrier) {
             this.cyclicBarrier = cyclicBarrier;
         }

         @Override
         public void run() {
             Log.d(TAG, "线程"+Thread.currentThread().getName()+"正在写入数据...");
             try {
                 Thread.sleep();      //以睡眠来模拟写入数据操作
                 Log.d(TAG, "线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
                 try {
                     cyclicBarrier., TimeUnit.MILLISECONDS);//等待了指定的时间(2ms)发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务
                 } catch (TimeoutException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }catch(BrokenBarrierException e){
                 e.printStackTrace();
             }
             Log.d(TAG, Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");
         }
     }

4.Semaphore示例

     void testSemaphore() {
         ;            //工人数
         Semaphore semaphore = ); //机器数目
         ; i < N; i++)
             new Worker(i, semaphore).start();
     }

     static class Worker extends Thread {
         private int num;
         private Semaphore semaphore;

         public Worker(int num, Semaphore semaphore) {
             this.num = num;
             this.semaphore = semaphore;
         }

         @Override
         public void run() {
             try {
                 semaphore.acquire();
                 Log.d(TAG,"工人" + this.num + "占用一个机器在生产...");
                 Thread.sleep();
                 Log.d(TAG,"工人" + this.num + "释放出机器");
                 semaphore.release();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }

java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore的更多相关文章

  1. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  2. Java中Collection、Map常用实现类研究分析

    接口/实现类 描述 key是否可为null 为null是否报错 key是否重复 key重复是否报错 key是否和添加一致 是否线程安全 List 一组元素的集合 ArrayList 基于数组存储,读取 ...

  3. Java中创建线程的三种方式以及区别

    在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...

  4. 浅谈利用同步机制解决Java中的线程安全问题

    我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...

  5. 【Java中的线程】java.lang.Thread 类分析

    进程和线程 联想一下现实生活中的例子--烧开水,烧开水时是不是不需要在旁边守着,交给热水机完成,烧开水这段时间可以去干一点其他的事情,例如将衣服丢到洗衣机中洗衣服.这样开水烧完,衣服洗的也差不多了.这 ...

  6. 关于Java中的线程安全(线程同步)

    java中的线程安全是什么: 就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问 什么叫 ...

  7. Java中的线程同步

    Java 中的线程同步问题: 1. 线程同步: 对于访问同一份资源的多个线程之间, 来进行协调的这个东西. 2. 同步方法: 当某个对象调用了同步方法时, 该对象上的其它同步方法必须等待该同步方法执行 ...

  8. JAVA基础——Java 中必须了解的常用类

    Java中必须了解的常用类 一.包装类 相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不 ...

  9. Java中的线程Thread总结

    首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...

随机推荐

  1. does not name a type

    一般都与头文件有关 1.缺少using namespaces std: 2.头文件的地方不对. 3.加错了头文件,还会出现内部函数库的报错.有的函数被多个函数库包含

  2. 黑盒测试实践--Day3 11.27

    黑盒测试实践--Day3 今天完成任务情况: 收到小组紧急通知,作业要求更新了.组长召集大家在下午课后去开个短会,会议信息如下: 时间:11.27 晚上5:30 地点:东九楼501 会议内容: 学习了 ...

  3. javascript总结18:javascript DOM简介

    1 HTML DOM 使 JavaScript 有能力对 HTML 事件做出反应.在事件发生时,执行JavaScript 方法,做出交互. 2 格式: onclick=JavaScript脚本 3 H ...

  4. Winform中的DatagridView显示行号

    1.设置 RowPostPaint 为true 2.启用RowPostPaint事件 /// <summary> /// DataGridView显示行号 /// </summary ...

  5. SQL Server 根据关键字和结束符提取字符串子串

    /* @info-待截取的字符串 @indexStr-截取子串的起始字符串 @split-截取子串的结束符号 列入依次传入 胸片:正常.心电图:异常,需要注意.血常规检查:正常. 心电图 '.' 返回 ...

  6. webservice不能序列化接口问题,返回值为IList或者参数为接口的解决办法。

    1. webservice 不能返回泛型接口集合IList,解决办法如下链接: 参考资料:http://www.cnblogs.com/yinhaiming/articles/1379424.html ...

  7. 扩展卢卡斯定理(Exlucas)

    题目链接 戳我 前置知识 中国剩余定理(crt)或扩展中国剩余定理(excrt) 乘法逆元 组合数的基本运用 扩展欧几里得(exgcd) 说实话Lucas真的和这个没有什么太大的关系,但是Lucas还 ...

  8. CentOS 6.9下PXE+Kickstart无人值守安装操作系统

    一.简介 1.1 什么是PXE PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持 ...

  9. retain, copy, assign区别

    1.retain, copy, assign区别 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b.此时a 和b ...

  10. python字符串常用方法、分割字符串等

    一.字符串的常用方法 1.str.capitalize()  字符串首字母大写 2.str.center()  把字符串居中 3.str.isalnum() 判断字符串是否含有英文.数字,若有英文和数 ...