CountDownLatch
CountDownLatch让一些线程阻塞,直到另外一些线程完成操作后 才被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其它线程调用countDown方法会将计数器减一(调用countDown方法的线程不会阻塞),当计数器的值变为0时,因调用await方法被阻塞的线程会被唤醒,继续执行
demo
/**
* CountDownLatch案例
*/
public class CountDownLatchDemo {
public static void main (String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getId()+"退出");
countDownLatch.countDown();//count--1
}).start();
}
//当count!=0,main线程会被阻塞,只有当count=0 才唤醒
countDownLatch.await();
System.out.println("main线程成功退出" );
}
}
结果
CyclicBarrier (人齐才发车)
思想就是先设置了一道屏障,使线程处于阻塞状态,只有当屏障解决,线程才能解除阻塞
demo
/**
* CyclicBarrier案例
*/
public class CyclicBarrierDemo {
public static void main (String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(()->{
System.out.println("第"+ finalI +"人上车");
//线程处于阻塞 等到值到5 才解决阻塞
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getId() + "come in");
}).start();
}
}
}
结果
Semaphore(信号量)
信号量用于两个目的:
一个是用于多个共享资源的互斥使用
另外一个是用于并发线程数的控制
其实synchronized 可以看成只有一个资源的Semaphore
争夺车位demo
import java.util.concurrent.Semaphore;
/**
* Semaphore信号量
*
*/
public class SemaphoreDemo {
/**
* 争夺车位demo
* @param args
*/
public static void main (String[] args) {
Semaphore semaphore = new Semaphore(2);//模拟6个车位
System.out.println("=========== 开始争抢车位 ===========");
for (int i = 0; i < 5; i++) {
new Thread(()->{
try {
semaphore.acquire(); //争夺资源
System.out.println(Thread.currentThread().getName()+"抢到车位");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+"停3秒钟离开");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//释放资源
}
}).start();
}
}
}
运行结果