减少计数 CountDownLatch
CountDownLatch类可以设置一个计数器,然后通过countDown方法进行减1操作,使用await方法等待计数器小于等于0,然后继续执行await方法之后的语句。
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//定义计数器的基础值
CountDownLatch count = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"号完成");
count.countDown();
},String.valueOf(i)).start();
}
count.await();
System.out.println("所有完成");
}
}
循环栅栏 CyclicBarrier
一个同步的辅助类,允许一组线程互相等待,直到达到某个公共屏障点。
public class CyclicBarrierDemo {
//创建固定值
private static final int NUMBER = 7;
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(
NUMBER, new Runnable() {
@Override
public void run() {
System.out.println("神龙出现");
}
}
);
//寻找7个龙珠
for (int i = 1 ; i <= 7; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"星龙珠找到");
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
},String.valueOf(i)).start();
}
// 唤醒所需等待线程数
System.out.println(cyclicBarrier.getParties());
// 正在等待的线程数
System.out.println(cyclicBarrier.getNumberWaiting());
}
}
信号灯 Semaphore
信号量维护了一个许可集。如果有必要,在许可集可用前会阻塞每一个acquire(),然后再获得该许可,每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不适用实际的许可对象,Semaphore只对可用许可的号码进行计数,并采取相应的行动。
//6辆汽车 停在3个停车位
public class SemaphoreDemo {
public static void main(String[] args) {
// 表示3个许可
Semaphore semaphore = new Semaphore(3);
// 模拟6辆汽车
for (int i = 1; i <= 6; i++) {
new Thread(()->{
//抢占
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"---抢到了车位");
//随机停车时间
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();
}
}