JUC并发包
CountDownLatch倒计时器:
让一些线程阻塞直到另一些线程完成一系统操作后才被唤醒。一个 CountDownLatch 用给定的计数初始化。await() 方法阻塞,直到由于countDown() 方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的 await() 调用立即返回。 这是一个一次性的现象 - 计数无法重置。
举个例子:我们的API接口响应时间被要求在200ms以内,但是如果一个接口内部依赖多个三方/外部服务,那串行调用接口的响应时间必然很久,所以可使用内部服务并行调用进行优化。假设接口内部依赖了10个外部服务,创建CountDownLatch实例,计数数量为10,有10个线程来完成任务,等待在CountDownLatch上的线程执行完才能继续执行那个响应时间较快的接口。latch.countDown();方法作用是通知CountDownLatch有一个线程已经准备完毕,倒计数器可以减一了。latch.await()方法要求主线程等待所有10个检查任务全部准备好才一起并行执行。
一种典型的场景就是火箭发射。在火箭发射前,为了保证万无一失,往往还要进行各项设备、仪器的检测。只有等到所有的检查完毕后,引擎才能点火。那么在检测环节当然是多个检测项可以同时进行的
Semaphore信号灯:
多个共享资源互斥使用,控制线程并发数量,多个线程抢多个资源。
1、Semaphore信号量作为一种流控手段,可以对特定资源的允许同时访问的操作数量进行控制,例如池化技术(连接池)中的并发数,有界阻塞容器的容量等。
2、Semaphore中包含初始化时固定个数的许可,在进行操作的时候,需要先acquire获取到许可,才可以继续执行任务,如果获取失败,则进入阻塞;处理完成之后需要release释放许可。
3、acquire与release之间的关系:在实现中不包含真正的许可对象,并且Semaphore也不会将许可与线程关联起来,因此在一个线程中获得的许可可以在另一个线程中释放。可以将acquire操作视为是消费一个许可,而release操作是创建一个许可,Semaphore并不受限于它在创建时的初始许可数量。也就是说acquire与release并没有强制的一对一关系,release一次就相当于新增一个许可,许可的数量可能会由于没有与acquire操作一对一而导致超出初始化时设置的许可个数。 举例,有六台车抢三个停车位。
CyclicBarrier循环栅栏:
当多个线程一起执行任务是,一个线程没有完成任务,其他线程都必须进入等待状态,等待这个线程完成任务后,才能再执行其他任务。强调相互等待,一个线程不完成,其他线程全部等待。
创建CyclicBarrier时,它默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量。调用await方法的线程告诉CyclicBarrier自己已经到达同步点,然后当前线程被阻塞。
例如:一个公司去团建,需要大家全部集合完毕后,才能出发,有一个人员不到,全员都得等待。它的作用就是会让所有线程都等待完成后才会继续下一步行动
本文介绍了Java并发工具包中的CountDownLatch倒计时器,用于协调线程执行;Semaphore信号灯,控制共享资源并发访问;以及CyclicBarrier循环栅栏,确保线程同步完成任务。通过火箭发射和团队建设比喻,展示了这些工具在实际场景中的应用。
422





