文章目录
- CountDownLatch 减少计数
-
- 场景
- CyclicBarrier 循环屏障
-
- 场景
- Semaphore 信号量
-
- 场景
JUC 中提供了三种常用的辅助类, 通过这些辅助类可以很好的解决线程数量过多时 Lock 锁的频繁操作
CountDownLatch 减少计数
- CountDownLatch 类可以设置一个计数器, 然后通过 countDown 方法来进行减1 的操作
- 使用await() 方法等待计数器为0, 然后继续执行 await() 方法之后的语句
- 当一个或多个线程调用 await() 方法时, 这些线程会阻塞
- 其他线程调用 countDown 方法会将计数器减1(调用 countDown 方法的线程不会阻塞)
- 当计数器的值变为 0 时, 因 await() 方法阻塞的线程会被唤醒, 继续执行
场景
6个同学陆续离开教室后班长才可以关门
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+ "同学离开教室");
countDownLatch.countDown();
}
},String.valueOf(i)).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("班长锁门啦!!!");
}
CyclicBarrier 循环屏障
CyclicBarrier 的构造方法的第一个参数是目标障碍数, 每次执行 CyclicBarrier.await() 方法, 障碍数就会加1
如果达到了目标障碍数, 就执行给定的屏障动作, 由最后一个进入屏障的线程执行
场景
6个同学陆续离开教室后班长才可以关门
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, new Runnable() {
@Override
public void run() {
System.out.println("班长锁门啦!");
}
});
for (int i = 0; i < 4; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 同学离开教室了");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
},String.valueOf(i)).start();
}
}
Semaphore 信号量
- Semaphore 的构造方法中传入的第一个参数是最大信号量(可以看成是最大线程池)
- 每个信号量只能分发一个许可证
- 使用 acquire() 方法获得许可证, 使用 release() 方法释放许可证
场景
抢车位, 6辆汽车, 3个停车位
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 抢到了停车位");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " --------释放了停车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}
},String.valueOf(i)).start();
}
}