对CountDownLatch、CyclicBarrier和Semaphore的理解

1. CountDownLatch  计数器,需等待全部线程执行完毕,在向下执行。含有一个内部类Sync实现了AQS 的共享模式  没有公平非公平之分

理解:new CountDownLatch(10) new对象传的10会赋值给AQS的state 等待所有线程执行完毕向下执行,这里需要等待10线程全部执行完,每有一个线程执行完毕,执行一个减一操作

方法:

countDown() 每有一个线程执行完毕调用此方法,方法底层对AQS的state进行减一,然后利用CAS原理调用unsafe类(java操作内存的类)compareAndSwapInt方法修改state的值。当值减为0时,AQS中队列中等待线程才可以执行。

await()

调用此方法,方法底层会去检查AQS的state值是否等于0,等于0代表就可以直接执行了,不等于0就是还需要在等待,就会让当前线程进入AQS的队列中等待。

await(long timeout, TimeUnit unit)

相对于await()方法只有一个等待时间,在AQS队列中等待的时间。时间一到的话就不管了直接执行。

2. CyclicBarrier 跟CountDownLatch很类似,也是一个计数器类型,需全部线程都到位在一起执行。 内部使用ReentrantLock,Condition实现功能

理解:new CyclicBarrier(10) new对象设置parties,count为10,10为需要一起等待得线程数,通俗就是说要执行得10个线程同时到达同步点在一起执行。 new CyclicBarrier(10,Runable) 当有10条线程到达同步点,执行Runable

方法:

await()

调用此方法就是告诉Cyclicbarrier自己已经到达同步点。底层对count--,count-- == 0代表最后一个线程到达同步点,就会调用nextGeneration()。此方法会唤醒所有线程,将parties重新赋值给count。如果不是最后线程,就调用Condition.await()进行等待。

线程陷入等待状态,发现以下情况就会唤醒其他线程:

最后一个线程到达,即index == 0

某个参与线程等待超时

某个参与线程被中断

调用了CyclicBarrier的reset()方法。该方法会将屏障重置为初始状态

3. Semaphore 含有一个内部类Sync实现了AQS 的共享模式,有公平锁非公平锁之分。new对象传true创建公平锁,不传默认非公平锁。 (2,true)

理解:Semaphore在构造时,需要传入许可证的数量,它最后传递给了AQS的state值。线程在调用acquire方法获取许可证时,如果Semaphore中许可证的数量大于0,许可证的数量就减1,线程继续运行,当线程运行结束调用release方法时释放许可证时,许可证的数量就加1。如果获取许可证时,Semaphore中许可证的数量为0,则获取失败,线程进入AQS的等待队列中,等待被其它释放许可证的线程唤醒。

方法:

acquire() 获取许可证 线程获取许可证就会被阻塞,直到Semaphore中可以获得到许可证为止,然后线程再获取这个许可证。

release() 释放许可证 当调用release方法时将向Semaphore中添加一个许可证,如果有线程因为获取许可证被阻塞时,它将获取到许可证并被释放;如果没有获取许可证的线程, Semaphore只是记录许可证的可用数量。

公平锁:FairSync中多一个对阻塞队列是否有等待的线程的检查,如果没有,就可以参与许可证的竞争;如果有,线程直接被插入到阻塞队列尾节点并挂起,等待被唤醒。

非公平锁:当一个线程A调用acquire方法时,会直接尝试获取许可证,而不管同一时刻阻塞队列中是否有线程也在等待许可证,如果恰好有线程C调用release方法释放许可证,并唤醒阻塞队列中第一个等待的线程B,此时线程A和线程B是共同竞争可用许可证,不公平性就体现在:线程A没任何等待就和线程B一起竞争许可证了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CountDownLatchCyclicBarrierSemaphore都是Java用于多线程编程的同步工具类,但它们有不同的作用和使用场景。 1. CountDownLatch CountDownLatch(倒计时门闩)是一个同步工具类,它允许一个或多个线程等待其他线程完成操作后再继续执行。CountDownLatch维护了一个计数器,初始值为线程数量,线程完成任务后计数器减1。当计数器为0时,等待线程继续执行。CountDownLatch的主要方法是await()和countDown()。 使用场景:CountDownLatch适用于一组线程等待另一组线程完成操作后再继续执行的场景。比如,主线程等待所有子线程完成初始化后再继续执行。 2. CyclicBarrier CyclicBarrier(循环屏障)是一个同步工具类,它允许一组线程相互等待,直到所有线程都到达某个屏障点后再继续执行。CyclicBarrier的主要方法是await()。 使用场景:CyclicBarrier适用于需要多个线程协同完成某个任务的场景。比如,多个线程同时执行某个操作,需要等待所有线程都执行完后再进行下一步操作。 3. Semaphore Semaphore(信号量)是一个同步工具类,它允许多个线程同时访问某个资源。Semaphore维护了一个许可证数量,线程需要先获取许可证才能访问资源,访问完后释放许可证。Semaphore的主要方法是acquire()和release()。 使用场景:Semaphore适用于需要限制线程数量访问某个资源的场景。比如,数据库连接池限制同时访问连接的线程数量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值