CountDownLatch
适用场景: 一个线程需要等待其他多个线程执行完以后才执行
CountDownLatch latch = new CountDownLatch(2);
Runnable r = ()->{
System.out.println(Thread.currentThread().getId()+":exe task...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
};
new Thread(r).start();
Thread.sleep(2000); //第二个线程延迟启动
new Thread(r).start();
latch.await();
System.out.println("all finished");
CyclicBarrier
适用场景:一批执行任务的线程 互相之间需要等待其他线程执行完任务才能一起继续下一个任务
CyclicBarrier barrier = new CyclicBarrier(2);
Runnable r = ()->{
System.out.println(Thread.currentThread().getId()+":exe task...");
try {
Thread.sleep(2000);
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getId()+"exe next task...");
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
Thread.sleep(3000);
t2.start();
Semaphore
思想是 提供 n个许可,线程执行任务时每次都来获取许可,任务结束时归还许可,当许可不足时,线程阻塞直到有足够的许可
适用场景:当需要控制并行数量时
Semaphore semaphore = new Semaphore(2);
//Semaphore semaphore2 = new Semaphore(2,true); // 第二个参数表示 是公平的(等待越久越优先)
Runnable r = ()-> {
try {
semaphore.acquire(); //获取许可 如果没有将阻塞 直到有
//semaphore.acquire(2); //可以一次获取多个 [许可]
System.out.println(Thread.currentThread().getId()+": 拿到许可,执行任务...");
Thread.sleep(2000);
semaphore.release(); //释放[许可]
} catch (InterruptedException e) {
e.printStackTrace();
}
};
new Thread(r).start();
new Thread(r).start();
new Thread(r).start();
娱乐部分
强行使用CountDownLatch实现CyclicBarrier的效果
CountDownLatch latch = new CountDownLatch(2);
Runnable r = ()->{
System.out.println(Thread.currentThread().getId()+":执行任务...");
try {
Thread.sleep(1000); //模拟执行任务花费时间
latch.countDown();
latch.await();
System.out.println(Thread.currentThread().getId()+":执行下一个任务...");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
new Thread(r).start();
Thread.sleep(2000);
new Thread(r).start();