1、减少计数CountDownLatch
案例演示:班长等待班上的6位同学离开后关上门。
此种情况会出现错误…….
public class CountDownLatchDemo {
public static void main(String[] args) {
for(int i=1;i<=6;i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"号同学离开了教室");
},String.valueOf(i)).start();
}
System.out.println(Thread.currentThread().getName()+"班长关门了");
}
}
1号同学离开了教室
3号同学离开了教室
main班长关门了
2号同学离开了教室
4号同学离开了教室
5号同学离开了教室
6号同学离开了教室
解决方案:使用CountDownLatch
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//创建CountDownLatch对象,设置初始值
CountDownLatch countDownLatch=new CountDownLatch(6);
//6个随机线程代表6个随机离开的学生
for(int i=1;i<=6;i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"号同学离开了教室");
//每离开一位同学计数器便减1
countDownLatch.countDown();
},String.valueOf(i)).start();
}
//当计数器的值不为0时,则main线程等待
countDownLatch.await();
System.out.println(Thread.currentThread().getName()+"班长关门了");
}
}
2、循环栅栏CyclicBarrier
案例:集齐七龙珠召唤神龙一样的道理,给线程设置好目标,当线程的数量达到之后,即会执行成功需要进行的操作。
public class CyclicBarrierDemo {
private static final int NUMBER=7;
public static void main(String[] args) {
//创建CyclicBarrier对象,设置数量以及目标达到后需要进行的操作
CyclicBarrier cyclicBarrier= new CyclicBarrier(NUMBER,()->{
System.out.println("七龙珠召唤神龙");
});
for(int i=1;i<=7;i++){
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"颗龙珠");
//未收集完则等待
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
3、信号灯Semaphore
案例:6个线程去抢占车位,并且在占用车位一定的时间后再离开。
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
//抢占车位
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + ":抢占到车位");
//随机设置占用车位的时间1-5秒
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + ":离开了车位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放车位
semaphore.release();
}
}, String.valueOf(i)).start();
}
}
}