并发 同步器CyclicBarrier(循环栅栏)、CountDownLatch(闭锁)、Semaphore(信号灯)---简单学习

CyclicBarrier:
  • java.util.concurrent.CyclicBarrier包下提供的一个同步器类,该类会等待指定个数的线程全部执行完后才执行后续逻辑。

该类提供了两个构造函数:

注:译自java api

CyclicBarrier(int parties)
创建一个新的循环栅栏,当给定的缔约方(线程)等待它时,它将会等待,并且当栅栏被等待时,它不会执行预先定义的操作

CyclicBarrier(int parties, Runnable barrierAction)

创建一个新的循环栅栏,当给定的缔约方(线程)等待它时,它将会等待,当障碍被触发时,它将执行给定的barrier动作,由最后一个进入屏障的线程执行

注:译自java api

int await()
等待直到所有各方都在这个障碍上等待。
int

await(long timeout, TimeUnit unit)

等待直到所有各方都在这个障碍上等待,或者指定的等待时间流逝。

int getNumberWaiting()
返回目前在隔离墙等候的缔约方的数量
int getParties()
返回到达此障碍所需的缔约方数量
boolean isBroken()
如果这个障碍处于一个破碎的状态。
void

reset()

将障碍重新设置为初始状态。

实例:



使用ArrayList会造成线程安全问题图解:

两个对象或多个,同时都拿到了空的ArrayList


使用线程安全vector,保证每次操作集合的都只是一个线程在进行,或者使用lock进行加锁:


这里使用了并发包下的ExecutorService,在执行完毕后应当关闭线程

二、CountDownLatch(闭锁)  

       其内部维护了一个计数器,每个线程结束后对计数器值进行减一,当count为0时表示所有线程执行完成才执行下一步操作。

CountDownLatch(int count)

构造一个用给定计数初始化的闭锁。

提供方法:

注:译自java api

void await()
使当前线程等待直到门闩数到零为止,除非线程被中断。
boolean await(long timeout, TimeUnit unit)
使当前线程等待直到门闩数到零为止,除非线程被中断,否则指定的等待时间就会流逝。
void countDown()
如果计数达到零,就会释放锁的计数,释放所有等待的线程。
long getCount()
返回当前计数。
String toString()
返回一个识别这个锁的字符串,以及它的状态。

await():该方法会在检查是否所有线程执行完毕,且cout值是否为0

实例:


多线程业务逻辑:



三、Semaphore(信号灯):

   该类内部维护了一个'许可证',多线程下执行每个线程都会去拿一个许可证,执行结束后释放许可证,若有许可证,并立即返回,将可获得的许可证数量减少一个。如果没有许可证可用,那么当前线程就会因线程调度的目的而被禁用,并且处于休眠状态。适用场景-多个对象轮番操作少于多个对象内容-如:3台机器7个工人轮番使用。

实例:


获取许可证和释放许可证:


结果:


若未进行release()释放许可证,则会出现未获得许可证的线程会一直等待并尝试获得许可证。

猜你喜欢

转载自blog.csdn.net/qq_28834183/article/details/80665668
今日推荐