CountDownLatch
count初始化CountDownLatch,然后需要等待的线程调用await方法。await方法会一直受阻塞直到count=0。而其它线程完成自己的操作后,调用countDown()使计数器count减1。当count减到0时,所有在等待的线程均会被释放
说白了就是通过count变量来控制等待,如果count值为0了(其他线程的任务都完成了),那就可以继续执行。
public class CountDownLatchTest {
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(5);
new Thread(new Runnable() {
@Override
public void run() {
try {
//在countDownLathch为0之前,用await()都会阻塞该线程。
countDownLatch.await();
System.out.println(Thread.currentThread().getId()+"终于能运行啦");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
for(int i=0;i<5;i++) {
new Thread(new Runnable() {
@Override
public void run() {
countDownLatch.countDown();
System.out.println(Thread.currentThread().getId()+"执行countDown()操作,此时countDownLatch值为"+countDownLatch);
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
输出结果:
image.png
CyclicBarrier
CountDownLatch注重的是等待其他线程完成,CyclicBarrier注重的是:当线程到达某个状态后,暂停下来等待其他线程,所有线程均到达以后,继续执行。
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
cyclicBarrier.await();
System.out.println("线程" + Thread.currentThread().getName() + "准备好啦");
cyclicBarrier.await();
System.out.println("线程" + Thread.currentThread().getName() + "登录了游戏");
cyclicBarrier.await();
System.out.println("线程" + Thread.currentThread().getName() + "打游戏咯");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
输出结果
image.png
Semaphore
Semaphore(信号量)实际上就是可以控制同时访问的线程个数,它维护了一组"许可证"。
当调用acquire()方法时,会消费一个许可证。如果没有许可证了,会阻塞起来
当调用release()方法时,会添加一个许可证。
这些"许可证"的个数其实就是一个count变量罢了~
特别注意的点!!!
当Semaphore的值设为0的时候,此时调用acquire()会阻塞当前线程,而如果先调用release()再调用acquire(),即可运行。(很重要,)
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(5);
for (int i = 0; i < 20; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿到通行证咯");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "归还通行证");
semaphore.release();
}
}).start();
}
}
}
输出描述:
image.png
网友评论