CountDownLatch(减少计算)
- CountDownLatch主要有两个方法,countDown()和await(),当一个或多个线程调用await方法时,这些线程会阻塞。
- 其他线程调用countDown()方法计数器减一(调用countDown方法的线程不会阻塞)
- 当计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行。
public class CountDownLatchDemo {
public static void main(String args[]) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6); //倒计数
for (int i = 1; i <= 6 ; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"\t"+"离开");
countDownLatch.countDown();
},i+"").start();
}
countDownLatch.await();
System.out.println("锁门");
}
}
CyclicBarrier(循环栅栏)
- 让一组线程到达一个屏障(也可以叫同步点)时被阻塞。
- 直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
- 线程进入屏障通过CyclicBarrier的await()方法。
public class CyclicBarrierDemo {
public static void main(String args[]){
//计数
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,() -> {
System.out.println("召唤神龙");
});
for (int i = 1; i <= 7; i++) {
new Thread(() -> {
System.out.println("收集到第:"+Thread.currentThread().getName()+"龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
Semaphore(信号灯)
在信号量上定义了两种操作:
- acquire(获取)当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减一),要么一直等下去,直到有线程释放信号量,或超时。
- release(释放)实际上会将信号量的值加1,然后唤醒等待的线程。
信号量主要用于两个目的,一是用于多个共享资源的互斥作用,二是用于并发线程数的控制。
public class SemaphoreDemo {
public static void main(String args[]){
//主要用于多线程资源的控制,信号的互斥控制
Semaphore semaphore = new Semaphore(3); //模拟资源类,有3个空车位
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"\t"+"抢占到了车位");
//暂停一会儿线程
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"\t"+"离开了车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i+1)).start();
}
}
}