1.CountDownLatch
1.1.定义
CountDownLatch允许一个或者多个线程去等待其他线程完成操作。
CountDownLatch 接收一个int型参数,表示要等待的工作线程的个数。
1.2.方法
方法 | 描述 |
---|---|
await() | 使当前线程进入同步队列进行等待,直到latch的值被减到0或者当前线程被中断,当前线程就会被唤醒。 |
await(long timeout, TimeUnit unit) | 带超时时间的await()。 |
countDown() | 使latch的值减1,如果减到了0,则会唤醒所有等待在这个latch上的线程。 |
getCount() | 获得latch的数值。 |
1.3.example
两个等待线程等待三个工作线程完成后再执行
fun main() {
val countDownLatch: CountDownLatch = CountDownLatch(2)
val waitThread1 : WaitThread = WaitThread("waitThread1", countDownLatch)
val waitThread2 : WaitThread = WaitThread("waitThread2", countDownLatch)
val workThread1 : WorkThread = WorkThread("workThread1", countDownLatch)
val workThread2 : WorkThread = WorkThread("workThread2", countDownLatch)
val workThread3 : WorkThread = WorkThread("workThread3", countDownLatch)
waitThread1.start()
waitThread2.start()
Thread.sleep(1000)
workThread1.start()
workThread2.start()
workThread3.start()
}
class WaitThread(name: String, private val countDownLatch: CountDownLatch) : Thread() {
init {
this.name = name
}
override fun run() {
println(name + "is waiting...")
countDownLatch.await()
println(name + "is continue running...")
}
}
class WorkThread(name: String, private val countDownLatch: CountDownLatch) : Thread() {
init {
this.name = name
}
override fun run() {
println("$name is running...")
sleep(2)
println("$name is end...")
countDownLatch.countDown()
}
}
运行结果:
2.Semaphore
2.1.定义
通常称呼它为信号量,可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。
主要用于那些资源有明确访问数量限制的场景,常用于限流 。
比如:数据库连接池,同时进行连接的线程有数量限制,连接不能超过一定的数量,当连接达到了限制数量后,后面的线程只能排队等前面的线程释放了数据库连接才能获得数据库连接。
2.2.方法
方法 | 描述 |
---|---|
acquire() | 获取一个公共许可,公共许可-1,如果公共许可<0阻塞等待 |
acquire(int permits) | 获取permits个公共许可,公共许可-permits,如果公共许可<0阻塞等待 |
release() | 释放一个公共许可,公共许可+1 |
release(int permits) | 释放permits个公共许可,公共许可+permits |
boolean tryAcquire( ); | 尝试获取一个公共资源,可以获取返回true,不可以返回false |
boolean tryAcquire( int permits ) | 尝试获取permits个公共许可,可以获取返回true,不可以返回false |
availablePermits() | 返回可用的许可数量。 |
2.3.example
同时只能有两辆车进入停车场,其余的需要等待,现在停着的需要驶出后,其他的才可以进入
fun main() {
val semaphore: Semaphore = Semaphore(2)
for(i in 0..10){
val parkingThread = ParkingThread("car $i", semaphore)
parkingThread.start()
}
}
class ParkingThread(name: String, private val semaphore: Semaphore) : Thread(){
init {
this.name = name
}
override fun run() {
try {
println("$name 来到停车场")
if(semaphore.availablePermits() == 0) {
println("停车场无车位,$name 请等待")
}
semaphore.acquire()
println("$name 成功进入停车场")
sleep(1000)
println("$name 驶出停车场")
semaphore.release()
}catch (e: InterruptedException){
e.printStackTrace()
}
}
}
运行结果:
car 0 来到停车场
car 4 来到停车场
car 3 来到停车场
car 2 来到停车场
car 1 来到停车场
停车场无车位,car 2 请等待
car 4 成功进入停车场
car 0 成功进入停车场
car 6 来到停车场
car 5 来到停车场
停车场无车位,car 6 请等待
car 10 来到停车场
car 9 来到停车场
car 8 来到停车场
car 7 来到停车场
停车场无车位,car 1 请等待
停车场无车位,car 7 请等待
停车场无车位,car 8 请等待
停车场无车位,car 9 请等待
停车场无车位,car 10 请等待
停车场无车位,car 5 请等待
car 4 驶出停车场
car 3 成功进入停车场
car 0 驶出停车场
car 2 成功进入停车场
car 3 驶出停车场
car 6 成功进入停车场
car 2 驶出停车场
car 1 成功进入停车场
car 6 驶出停车场
car 7 成功进入停车场
car 1 驶出停车场
car 8 成功进入停车场
car 7 驶出停车场
car 9 成功进入停车场
car 8 驶出停车场
car 10 成功进入停车场
car 9 驶出停车场
car 5 成功进入停车场
car 10 驶出停车场
car 5 驶出停车场
Process finished with exit code 0