目录
简介
- CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
- CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;
- 而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
- 另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。
- Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。
CountDownLatch
// 子线程调用countDownLatch.await()进入等待队列
// 当调用countDownLatch.countDown()时,资源减1,没有资源时子线程继续运行
CountDownLatch countDownLatch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
try{
long startTime = System.currentTimeMillis();
countDownLatch.await();
long endTime = System.currentTimeMillis();
System.out.println("awaitTime : " + (endTime - startTime) / 1000 + "seconds");
} catch (InterruptedException e) {}
}
}).start();
Thread.sleep(5000);
countDownLatch.countDown();
cyclicBarrier
循环屏障,如果传入2,当2个cyclicBarrier.await()的线程都进入等待时,这三个线程不再等待,都继续执行。
CyclicBarrier barrier = new CyclicBarrier(2);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
barrier.await();
System.out.println("等待");
} catch (Exception e) {}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
barrier.await();
System.out.println("未等待");
} catch (InterruptedException | BrokenBarrierException e) {}
}
}).start();
Semaphore
前5个工人可以直接获取许可,但是后面的只能等待有许可时才能执行。
public class SemaphoreTest {
public static void main(String[] args) {
int N = 8; //工人数
Semaphore semaphore = new Semaphore(5); //机器数目
for(int i=0;i<N;i++){
new Worker(i,semaphore).start();
}
}
static class Worker extends Thread{
private int num;
private Semaphore semaphore;
public Worker(int num,Semaphore semaphore){
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("工人"+this.num+"占用一个机器在生产...");
Thread.sleep(2000);
System.out.println("工人"+this.num+"释放出机器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
参考:
1、https://www.cnblogs.com/dolphin0520/p/3920397.html
2、https://blog.youkuaiyun.com/m0_37343985/article/details/83037458