CountDownLatch
减法器:等待多线程完成,允许一个或多个线程等待其他线程完成操作
举例:门卫关门,教室里面有10个同学,必须所有同学全部出去之后再关门
创建对象:CountDownLatch downLatch = new CountDownLatch(10);
// 每个线程执行依次任务,就让减法计数器中的值减少一个
放在线程任务中:downLatch.countDown();
// 当downLatch中的值从10减少到0时,才执行后面的代码,否则阻塞
放在外面:downLatch.await();
流程:
1. 使用减法计数器创建对象,确定最大值,如10
2. 使用匿名内部类Runnable,重写run()方法创建10个学生的线程任务
3. 内部类中每个线程依次执行任务,就让减法计数器的值减少一次
4. 开启10个学生线程
5. 当downLatch中的值从10减少到0时,才执行后面的代码,否则阻塞
6. 启动关门线程
CyclicBarrier
加法器:可以让一批线程之间相互等待,等到某一个临界值的时候,再同时往下执行
举例:108张卡片兑换学习机
创建对象:CyclicBarrier cyclicBarrier = new CyclicBarrier(108);
// 让加法计数器中的值+1 2. 判断增加之后的这个值是否为108 , 没达到就阻塞
放在线程里面:barrier.await();
流程:
1. 创建加法计数器和匿名内部类Runnable,重写run()方法,确定等待的值,如108和达到108之后执行的语句
2. 使用匿名内部类Runnable创建108个线程的共同任务
3. 在内部类中让加法计数器的值加一,判断增加之后的值是否达到108,没有则等待
4. 开启108个线程
Semaphore
信号量:控制并发访问的最大线程数量
举例:停车场,五个车位,最多同时停五辆车
构造方法:public Semaphore(int permits)
方法:public void acquire() : 获取许可权
public void release() : 失去许可权
流程:
1. 创建信号量对象
2. 使用匿名内部类Runnable创建停车线程任务
3. 在进入之前线获取到许可证
4. 在内部类中所有代码执行完毕后失去许可证
5. 开启10个线程开始停车
// 1. 创建信号量对象
Semaphore sema = new Semaphore(5);
// 2. 创建停车线程任务
Runnable task = new Runnable() {
@Override
public void run() {
// 进入之前获得停车许可证
try {
sema.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 模拟停车
System.out.println(Thread.currentThread().getName()+"进入停车场");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 执行完毕失去停车许可
System.out.println(Thread.currentThread().getName()+"离开停车场");
// 离开之后失去停车许可证
sema.release();
}
};
// 3. 开启10个线程开始停车
for (int i = 1; i <= 1000; i++) {
new Thread(task,"车"+i).start();
}
并发线程工具类
最新推荐文章于 2024-08-16 23:08:28 发布