AI智能
改变未来

Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo


Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

CountDownLatch

countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

CountDownLatch中的方法

//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行public void await() throws InterruptedException { };//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };//将count值减1public void countDown() { };

CountDownLatchDemo

条件改为i<20时,并不会输出“完结撒花”,因为latch还没有减到0

import java.util.concurrent.CountDownLatch;public class CountDownLatchDemo {public static void main(String[] args)  {CountDownLatch latch = new CountDownLatch(20);//条件改为i<20时,并不会输出“完结撒花”,因为latch还没有减到0for (int i = 0; i < 20; i++) {int index=i;new Thread(new Runnable() {@Overridepublic void run() {latch.countDown();System.out.println(index);}}).start();}try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("完结撒花");}}

CyclicBarrier

CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。

  • CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的

构造方法

public CyclicBarrier(int parties)public CyclicBarrier(int parties, Runnable barrierAction)
  • parties 是参与线程的个数
  • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务

方法

public int await() throws InterruptedException, BrokenBarrierExceptionpublic int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
  • 线程调用 await() 表示自己已经到达栅栏
  • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时

Demo

  • 初始化线程1,线程1睡眠3秒
  • 剩余九个线程到达barrier,但是并不会又输出
  • 三秒后线程1到达,9个线程开始输出
import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier barrier = new CyclicBarrier(10);//初始化线程1,线程1睡眠3秒,等待剩余九个线程到达barriernew Thread(new Runnable() {@Overridepublic void run() {try {Thread.currentThread().sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}try {barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}).start();//九个线程先到达barrierfor (int i = 0; i < 9; i++) {int index=i;new Thread(new Runnable() {@Overridepublic void run() {try {barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(index);}}).start();}}}//Output,输出是随机的/*062187435*/

Semaphore

Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

常用方法

  void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。  void release():释放一个许可,将其返回给信号量。  int availablePermits():返回此信号量中当前可用的许可数。  boolean hasQueuedThreads():查询是否有线程正在等待获取。

Demo

  • 六个人竞争三个办事窗口,每个办事窗口只能容纳三个人,输出如下
package ConcurrentApi;import java.util.concurrent.Semaphore;//Output/*线程0等到了办事窗口空闲办事窗口剩余量2线程1等到了办事窗口空闲办事窗口剩余量1线程2等到了办事窗口空闲办事窗口剩余量0线程3等到了办事窗口空闲办事窗口剩余量0线程4等到了办事窗口空闲办事窗口剩余量0线程5等到了办事窗口空闲办事窗口剩余量0*/public class SemaphoreDemo {public static void main(String[] args) {//初始化3 三个办事窗口Semaphore semaphore = new Semaphore(3);for (int i = 0; i < 6; i++) {int index = i;try {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}new Thread(new Runnable() {@Overridepublic void run() {try {semaphore.acquire();System.out.println("线程"+index+"等到了办事窗口空闲");System.out.println("办事窗口剩余量"+semaphore.availablePermits());} catch (InterruptedException e) {e.printStackTrace();}try {Thread.currentThread().sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}semaphore.release();}}).start();}}}
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo