A CountDownLatch (blocking), Semaphore (semaphore), CyclicBarrier

A, CountDowmLatch (latching) (down counter latch)

  CountDownLatch class java.util.concurrent package located under, upon completion of certain operations, the only other all the threads of operations completed, the current operation has to be continued.

  Use it to achieve a similar counter functions. For example, there is a task A, it waits for the other to perform after the completion of four tasks to perform, then you can use CountDownLatch to implement this function.

. 1  Final a CountDownLatch LATCH = new new a CountDownLatch (2 );
 2  new new the Thread () {
 . 3      public  void RUN () {
 . 4          . System.out.println ( "child thread" + Thread.currentThread () getName () + " being executed" );
 . 5          the Thread.sleep (3000 );
 . 6          System.out.println ( "child thread" + Thread.currentThread () getName () + " finished." );
 . 7          latch.countDown ();
 . 8      };
 . 9  } .start ();
 10  new new the Thread () { 
 . 11      public  void RUN () {
 12 is         System.out.println ( "child thread" + Thread.currentThread () getName () + " executing." );
 13 is          the Thread.sleep (3000 );
 14          System.out.println ( "child thread" + Thread.currentThread () .getName () + "finished" );
 15          latch.countDown ();
 16      };
 . 17  } .start ();
 18 is System.out.println ( "waiting thread is finished sub 2 ..." );
 . 19  latch.await ();
 20 is System.out.println ( "thread has finished sub 2" );
 21 is System.out.println ( "main thread to continue" );
 22 }

Two, Semaphore (semaphore - controlling the number of threads simultaneously accessed)

  Semaphore can control the number of threads simultaneously access, obtain a license by acquire (), if not to wait, but a license is released by release ().

More important Semaphore class in a few ways:

  1) public void acquire (): used to obtain a license, if no license can be obtained, it will have to wait, knowing that permission.

  2) public void acquire (int permits): obtain permits licenses.

  3) public void release () {}: free license, attention, before releasing the license, must be licensed.

  4) public void release (int permits) {}: Permits release licenses.

The above four methods will be blocked, if you want to immediately get the results, you can use the following several methods:

  1) public boolean tryAcquire (): try to obtain a license, if the acquisition is successful, then immediately returns true, if the acquisition fails, it immediately returns false.

  2) public boolean tryAcquire (long timeout, TimeUnit unit): attempts to obtain a license, if succeed within the specified time, then immediately return true, otherwise it immediately returns false.

  3) public boolean tryAcquire (int permits): attempts to obtain permits licenses, if the acquisition is successful, then immediately returns true, if the acquisition fails, it immediately returns false.

  4) public boolean tryAcquire (int permits, long timeout, TimeUnit unit): attempts to obtain permits licenses, if succeed within the specified time, then immediately return true, otherwise it immediately returns false.

  5) may also be () method to get the number of available licenses by availablePermits.

  Example: If a factory has five machines, one machine at the same time can only be used by a worker, just ran out, the other workers to continue. Then we can be done by Semaphore:

 1 int N = 8; //工人数
 2 Semaphore semaphore = new Semaphore(5); //机器数目
 3 for(int i=0;i<N;i++){
 4     new Worker(i,semaphore).start();
 5 }
 6 static class Worker extends Thread{
 7     private int num;
 8     private Semaphore semaphore;
 9     public Worker(int num,Semaphore semaphore){
10         this.num = num;
11         this.semaphore = semaphore;
12     }
13     public void run() {
14         try {
15             semaphore.acquire();
16             System.out.println("工人"+this.num+"占用一个机器在生产...");
17             Thread.sleep(2000);
18             System.out.println("工人"+this.num+"释放出机器");
19             semaphore.release();
20         } catch (InterruptedException e) {
21             e.printStackTrace();
22         }
23     }
24 }

三、CyclicBarrier(回环栅栏-等待至barrier状态再全部同时执行)

  回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行,叫做回环,是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。我们暂且把这种状态叫做barrier,当调用await()方法之后,线程就处于barrier了。

  CyclicBarrier中最重要的方法就是await方法,它有两个重载版本:

    1)public int await():用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务。

    2)public int await(long timeout,TimeUnit unit):让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。

  具体使用如下:

 1  public static void main(String[] args) {
 2      int N = 4;
 3      CyclicBarrier barrier = new CyclicBarrier(N);
 4      for(int i=0;i<N;i++)
 5          new Writer(barrier).start();
 6      }
 7  static class Writer extends Thread{
 8      private CyclicBarrier cyclicBarrier;
 9      public Writer(CyclicBarrier cyclicBarrier) {
10          this.cyclicBarrier = cyclicBarrier;
11      }
12  public void run() {
13      try {
14          Thread.sleep(5000); //以睡眠来模拟线程需要预定写入数据操作
15 System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
16          cyclicBarrier.await();
17      } catch (InterruptedException e) {
18          e.printStackTrace();
19      }catch(BrokenBarrierException e){
20          e.printStackTrace();
21      }
22      System.out.println("所有线程写入完毕,继续处理其他任务,比如数据操作");
23      }
24  }

 

三者之间的联系与区别:

  CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。CountDownLatch一般用于某个线程A等待若干个线程执行完任务之后,它才执行;而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行。另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

  Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。

Guess you like

Origin www.cnblogs.com/HuiH/p/11904898.html