zoukankan      html  css  js  c++  java
  • java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore

    转自:

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

    1.简介

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

    2.CountDownLatch示例

     1    void testCountDownLatch() {
     2         final CountDownLatch latch = new CountDownLatch(2);
     3         new Thread() {
     4             public void run() {
     5                 try {
     6                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "正在执行");
     7                     Thread.sleep(3000);
     8                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "执行完毕");
     9                     latch.countDown();
    10                 } catch (InterruptedException e) {
    11                     e.printStackTrace();
    12                 }
    13             }
    14 
    15             ;
    16         }.start();
    17 
    18         new Thread() {
    19             public void run() {
    20                 try {
    21                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "正在执行");
    22                     Thread.sleep(3000);
    23                     Log.d(TAG, "子线程" + Thread.currentThread().getName() + "执行完毕");
    24                     latch.countDown();
    25                 } catch (InterruptedException e) {
    26                     e.printStackTrace();
    27                 }
    28             }
    29 
    30             ;
    31         }.start();
    32 
    33         try {
    34             Log.d(TAG, "等待2个子线程执行完毕...");
    35             latch.await();
    36             Log.d(TAG, "2个子线程已经执行完毕");
    37             Log.d(TAG, "继续执行主线程");
    38         } catch (InterruptedException e) {
    39             e.printStackTrace();
    40         }
    41     }

    3.CyclicBarrier示例

      1 static class Writer extends Thread {
      2         private CyclicBarrier cyclicBarrier;
      3 
      4         public Writer(CyclicBarrier cyclicBarrier) {
      5             this.cyclicBarrier = cyclicBarrier;
      6         }
      7 
      8         @Override
      9         public void run() {
     10             Log.d(TAG, "线程" + Thread.currentThread().getName() + "正在写入数据...");
     11             try {
     12                 Thread.sleep(5000);      //以睡眠来模拟写入数据操作
     13                 Log.d(TAG, "线程" + Thread.currentThread().getName() + "写入数据完毕,等待其他线程写入完毕");
     14                 cyclicBarrier.await();
     15             } catch (InterruptedException e) {
     16                 e.printStackTrace();
     17             } catch (BrokenBarrierException e) {
     18                 e.printStackTrace();
     19             }
     20             Log.d(TAG, "所有线程写入完毕,继续处理其他任务...");
     21         }
     22     }
     23 
     24 
     25     //用来阻塞当前线程,直至所有线程都到达barrier状态再同时执行后续任务;
     26     void testCyclicBarrier1(){
     27         int N = 4;
     28         CyclicBarrier barrier = new CyclicBarrier(N);
     29         for (int i = 0; i < N; i++) {
     30             new Writer(barrier).start();
     31         }
     32     }
     33 
     34     //如果说想在所有线程写入操作完之后,进行额外的其他操作可以为CyclicBarrier提供Runnable参数
     35     void testCyclicBarrier2(){
     36         int N = 4;
     37         CyclicBarrier barrier = new CyclicBarrier(N, new Runnable() {
     38             @Override
     39             public void run() {
     40                 Log.d(TAG, "当前线程" + Thread.currentThread().getName());
     41             }
     42         });
     43 
     44         for (int i = 0; i < N; i++){
     45             new Writer(barrier).start();
     46         }
     47     }
     48 
     49     //CyclicBarrier是可以重用的
     50     void testCyclicBarrier3(){
     51         int N = 4;
     52         CyclicBarrier barrier = new CyclicBarrier(N);
     53 
     54         for (int i = 0; i < N; i++) {
     55             new Writer(barrier).start();
     56         }
     57 
     58         try {
     59             Thread.sleep(25000);
     60         } catch (InterruptedException e) {
     61             e.printStackTrace();
     62         }
     63 
     64         Log.d(TAG, "CyclicBarrier重用");
     65 
     66         for (int i = 0; i < N; i++) {
     67             new Writer(barrier).start();
     68         }
     69     }
     70 
     71     //故意让最后一个线程启动延迟,因为在前面三个线程都达到barrier之后,
     72     //等待了指定的时间发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务。
     73     void testCyclicBarrier4(){
     74 
     75         int N = 4;
     76         CyclicBarrier barrier = new CyclicBarrier(N);
     77 
     78         for (int i = 0; i < N; i++) {
     79             if (i < N - 1)
     80                 new Writer2(barrier).start();
     81             else {
     82                 try {
     83                     Thread.sleep(5000);
     84                 } catch (InterruptedException e) {
     85                     e.printStackTrace();
     86                 }
     87                 new Writer(barrier).start();
     88             }
     89         }
     90     }
     91     static class Writer2 extends Thread{
     92         private CyclicBarrier cyclicBarrier;
     93         public Writer2(CyclicBarrier cyclicBarrier) {
     94             this.cyclicBarrier = cyclicBarrier;
     95         }
     96 
     97         @Override
     98         public void run() {
     99             Log.d(TAG, "线程"+Thread.currentThread().getName()+"正在写入数据...");
    100             try {
    101                 Thread.sleep(5000);      //以睡眠来模拟写入数据操作
    102                 Log.d(TAG, "线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
    103                 try {
    104                     cyclicBarrier.await(2000, TimeUnit.MILLISECONDS);//等待了指定的时间(2ms)发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务
    105                 } catch (TimeoutException e) {
    106                     // TODO Auto-generated catch block
    107                     e.printStackTrace();
    108                 }
    109             } catch (InterruptedException e) {
    110                 e.printStackTrace();
    111             }catch(BrokenBarrierException e){
    112                 e.printStackTrace();
    113             }
    114             Log.d(TAG, Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");
    115         }
    116     }

    4.Semaphore示例

     1     void testSemaphore() {
     2         int N = 8;            //工人数
     3         Semaphore semaphore = new Semaphore(5); //机器数目
     4         for (int i = 0; i < N; i++)
     5             new Worker(i, semaphore).start();
     6     }
     7 
     8     static class Worker extends Thread {
     9         private int num;
    10         private Semaphore semaphore;
    11 
    12         public Worker(int num, Semaphore semaphore) {
    13             this.num = num;
    14             this.semaphore = semaphore;
    15         }
    16 
    17         @Override
    18         public void run() {
    19             try {
    20                 semaphore.acquire();
    21                 Log.d(TAG,"工人" + this.num + "占用一个机器在生产...");
    22                 Thread.sleep(2000);
    23                 Log.d(TAG,"工人" + this.num + "释放出机器");
    24                 semaphore.release();
    25             } catch (InterruptedException e) {
    26                 e.printStackTrace();
    27             }
    28         }
    29     }
  • 相关阅读:
    201671010115 2016-2017-2《面向对象的程序设计》 Java学习计划
    201671010115 2016-2017-2《Java程序设计》第十八周Java心得
    201671010115 2016-2017-2《面向对象的程序设计》 java 第十六周学习心得
    201671010115 2016-2017-2《Java程序设计》第十五周Java心得
    201671010115 2016-2017-2《面向对象的程序设计》 java第十四周学习心得
    201671010115 2016-2017-2《Java程序设计》第十二周Java心得
    201671010115 2016-2017-2《Java程序设计》第十一周Java心得
    201671010115 2016-2017-2《Java程序设计》第十一周Java心得
    201671010115 2016-2017-2《Java程序设计》第十周Java学习心得
    201671010115 2016-2017-2《Java程序设计》第九周Java心得
  • 原文地址:https://www.cnblogs.com/mhbs/p/7631502.html
Copyright © 2011-2022 走看看