一、JUC相关的辅助类
减少计数CountDownLatch:
概念:
- CountDownLatch就是一个计数器,类似 - - 操作,没调用一次countDown就会减一。通过await方法来使其他线程阻塞,但调用countDown方法的线程不会阻塞,直到计数器为0才会唤醒await其他线程。
使用:
不使用countDownLatch
public static void main(String[] args) {
for (int i = 0; i < 4; i++) {
new Thread(() -> {
System.out.println( Thread.currentThread().getName() + "执行操作");
},"线程名称:" + i).start();
}
System.out.println("main 方法执行了");
}
可以看到main线程先执行了,接着我们使用countDownLatch
public static void main(String[] args) throws InterruptedException {
CountDownLatch downLatch = new CountDownLatch(4);
for (int i = 0; i < 4; i++) {
new Thread(() -> {
System.out.println( Thread.currentThread().getName() + "执行操作");
downLatch.countDown();
},"线程名称:" + i).start();
}
downLatch.await();
System.out.println("main 方法执行了");
}
多次执行的结果显示主线程永远在最后,这样就可以得到我们想要的结果
循环栅栏CyclicBarrier:
概念:
- 创建CyclicBarrier实例时需要指定数量的线程,并且传入一个callable接口,该接口中的任务会在其它执行数量的线程执行完以后才会执行。其实就类似于满足条件才会执行,不然就一直等待。
使用:
public class CyclicBarrierDemo {
private static final Integer NUMBER = 5;
public static void main(String[] args) {
CyclicBarrier cyclicBarrier =
new CyclicBarrier(NUMBER,
() -> System.out.println("满足循环栅栏条件,执行了")
);
for (int i = 1; i <= 5; i++) {
new Thread(() -> {
try {
System.out.println("开始循环," + Thread.currentThread().getName() + "执行中");
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
},"线程名称:" + i).start();
}
}
}
信号灯Semaphore:
概念:
- 限定数量的资源,多个任务来抢占限定的资源,类似加锁释放锁的操作,抢占成功会获得一个信号,执行完任务后会释放信号。直至所有的任务执行完毕
使用:
public static void main(String[] args) {
// 限定三个资源
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "抢占资源");
//执行任务
System.out.println(Thread.currentThread().getName() + "任务执行完毕离开");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放资源
semaphore.release();
}
},"线程名称:" + i).start();
}
}
执行结果