CountDownLatch
CountDownLatch类可以设置一个计数器,然后通过countDown方法来进行减1的操作,使用await方法等待计数器不大于0,然后继续执行await方法之后的语句。
package demo_04;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
// JUC中常用的三大辅助类 一CountDownLatch
public class test_01 {
public static void main(String[] args) throws InterruptedException {
// 计数器值是6
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" Go Out!");
countDownLatch.countDown(); // 计数器减1
},String.valueOf(i)).start();
}
countDownLatch.await(); // 等待计数器不大于0 再继续执行否则一直阻塞
System.out.println("计数器已经归0啦!");
}
}
执行结果:
CyclicBarrier
CyclicBarrier看英文单词可以看出大概就是循环阻塞的意思,在使用中CyclicBarrier的构造方法第一个参数是目标障碍数,每次执行CyclicBarrier一次障碍数会加一,如果达到了目标障碍数,才会执行cyclicBarrier.await()之后的语句。可以将CyclicBarrier理解为加1操作
package demo_04;
// JUC中常用的三大辅助类 CyclicBarrier
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class test_02 {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5,()->{ // 如果没有达到5,cyclicBarrier.await()会一直阻塞
System.out.println("奥运五环!");
});
for (int i = 1; i <= 5; i++) {
new Thread(()->{
System.out.println(" 第 "+Thread.currentThread().getName()+" 环 ");
try {
cyclicBarrier.await(); // 可以简单的理解每次+1
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
Semaphore
Semaphore的构造方法中传入的第一个参数是最大信号量(可以看成最大线程池),每个信号量初始化为一个最多只能分发一个许可证。使用acquire方法获得许可证,release方法释放许可。Semaphore默认使用的非公平锁,在信号量都被使用的时候会阻塞等待线程释放信号量(默认不会出现抢占情况)。
package demo_04;
// JUC中常用的三大辅助类 Semaphore
import java.sql.Time;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class test_03 {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
semaphore.acquire(); // 获得资源
System.out.println(Thread.currentThread().getName()+" 得到了资源。");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+" 释放了资源.");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release(); // 释放资源
}
},String.valueOf(i)).start();
}
}
}