多线程中的控制并发流程的工具类

1、CountDownLatch(倒计时门闩)

(1)流程

CountDownLatch是事件驱动的,当计数不断减少达到到0时,等待的线程(调用CountDownLatch.await()的线程)会被唤醒。

 (2)主要方法

 a、构造函数:传入要倒计数的次数

 b、await:让调用的线程进入阻塞状态,直到计数为0

 c、countDown():倒计数

(3)用法:

一等多:一个线程等待多个线程运行完成(并行运行,但完成顺序有先后)后开始运行,常用场景如检查

多等一:在一个线程countDown后,多个线程同时开始运行,常用场景如抢购

多等多

代码实例:

 

 (4)注意点

        a、CountDownlatch是事件驱动的,调用await()和countDown()的不一定是同一个线程

        b、CountDownlatch不能重用,在倒计时完成后,再调用await()不会阻塞。

2、CyclicBarrier(循环栅栏)

(1)流程:

线程调用await()方法阻塞,当调用await()的线程达到一定数量后,同时唤醒所有线程

(2)主要方法

         a、构造函数CyclicBarrier(int,Runable):传入阻塞的线程数和到达阻塞数量后运行的方法

         b、await():挂起当前线程,当达到一定数量的线程后继续运行。

(3)用法

 让线程阻塞到指定数量后,一起运行。

 

 (4)与CountDownLatch的不同

        a、CountDownLatch是倒数事件驱动的,倒数了一定的次数后放行,在一个线程中可以进行多次的倒数,而CyclicBarrier是线程数量驱动的,只有阻塞的线程达到一定数量后才放行。

        b、CountDownLatch不能重复使用,而CyclicBarrier能够重复使用

        c、CyclicBarrier能在触发放行的同时做一定的工作,即构造函数中传入的Runnable接口

3、Semaphore(信号量)

(1)作用:类似于许可证的作用,设置一层的过滤,用来控制对有限资源的使用

(2)使用流程

初始化Semaphore来指定许可证的数量,调用acquire()获取许可证(有就能获取),运行结束后调用release()释放许可证。

 (3)主要方法:

 方法和ReentranLock相似

a、构造函数Semaphore(许可证数量,是否公平),默认不公平,和ReentranLock的公平,非公平策略相似;公平则进入等待队列进行排队,非公平则会先尝试去获取信号量,获取失败才进入等待队列。

b、获取信号量接口,acquire()能够响应中断,acquire(int)一次性可以拿多个数量的许可证,tryAcquire()尝试获取立即返回结果,带超时的tryAcquire()

c、释放realse(),与ReentranLock相似,不会自动释放,要手动释放

(4)代码实例:

 

 (5)注意点

a、对一个线程而言可以一次获取多个信号量和释放多个信号量,可以获取和释放的数量不一致

b、获取和释放许可证对线程无要求,可以A线程获取,B线程去释放。如下代码所示,初始化的数量并不代表信号量允许的最大数量,只要调用realse()剩余的信号量数量就会增加,无关总量,谁获取,谁释放。

 

 4、Condition接口

(1)作用:

Condition接口为Lock对象提供await(),signal(),signalAll()方法,类似于sychronized(Object)对应的Object.wait(),Object.notify(),Object.notifyAll()。

用于让持有锁的线程陷入waiting状态并释放锁,和唤醒waiting状态的对象

(2)主要方法

 

 a、signalAll()唤醒所有正在等待的线程

 b、signal()是公平的,唤醒等待时间最长的线程。

(3)用法:

a、Condition要与Lock绑定,通过ReentranLock.newCotion(),生成锁对应的Condition对象

b、与Object.wait(),Object.notify(),要在synchronized的同步代码块中一样,await()和signal()

也要在Lock.lock()和Lock.unlock()之间

(4)用Conditon实现生产者消费者模式:

一个Lock()对象生成两个Condition对象,分别来表示仓库未满和未空

 

 运行结果:

5、AQS(AbstractQueuedSynchronizer)

(1)AQS的作用:在ReentrantLock,Semaphore,CountDownLatch和ThreadPoolExceutor中都有成员是继承自AQS的,它的主要作用是:同步状态的原子性管理,排队队列的管理,线程的阻塞和解除阻塞;本质上是一个排队管理器。

 (2)AQS的3大组成核心

a、state用于表示状态,在不同的实现中有不同的意义

ReentrantLock中表示的就是锁的重入次数,0表示锁未被占有

Semaphore中表示的是剩余许可证的数量

CountDownlatch中剩余的要计数的次数

 b、控制线程抢锁和配合的FIFO队列

用于存放等待的线程,是一个双向的队列

c、继承的工具类要去实现的获取和释放等重要方法

 (3)AQS的用法

 a、继承的类实现自己特性的方法(如CountDownLatch中的countDown(),await()),这些方法本质上会调用ASQ的aquire(),release(),share方法

b、继承的类要覆盖protect修饰的try***方法,即实现自己的获取释放逻辑

c、AQS中的aquire(),release(),share方法回去调用覆盖过的try***方法。

(4)AQS挂起线程使用的是LockSupport.park()方法将线程从Runable变为waiting,所以它的效率是高于synchronized的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值