为了实现线程中的精准的相互通信控制,我们在JUC.locks包下**有Condition寄存器可以实现精准唤醒**,JUC还提供了一些**常用辅助类**帮助我们实现线程之间的相互控制。
1、CountDownLatch——减计数锁存器
-
使用方法:
CountDownLatch countDownLatch = new CountDownLatch(6); //创建锁存器 countDownLatch.countDown() //计数器减一 countDownLatch.await() //等待计数器归零再向下执行
-
形象记忆:
我们可以把它想成一个定时器,new CountDownLatch(6)初始化定义倒计时秒数,在某个A线程中执行countDownLatch.await(),相当于在该线程上安装了一个定时器,其他线程执行countDownLatch.countDown()操作时,倒计时秒数-1,直到倒计时完成,A线程继续执行。
-
代码案例:
//总数是6,必须要执行任务的时候在使用
CountDownLatch countDownLatch = new CountDownLatch(6); //创建锁存器(定时器)
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"走了");
countDownLatch.countDown(); 计数器减一
},String.valueOf(i)).start();
}
countDownLatch.await(); //安装定时器,等待倒计时结束继续执行下面程序
System.out.println("关门");
执行结果:
1走了
3走了
4走了
2走了
5走了
6走了
关门
2、CyclicBarrier——循环屏障
-
使用方法:
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{});// 创建栅栏 cyclicBarrier.await();//等待计数器到达计数值,执行runnalble的lambda表达式方法。
-
形象记忆:
我们可以把它想成一个栅栏,CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{});语句初始化栅栏承受能力和栅栏攻破后操作,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++) { final int temp = i; new Thread(()->{ System.out.println(temp); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } } 执行结果: 集齐第1颗龙珠 集齐第5颗龙珠 集齐第7颗龙珠 集齐第6颗龙珠 集齐第4颗龙珠 集齐第2颗龙珠 集齐第3颗龙珠 召唤神龙
-
注意:在for循环中,lambda表达式不能直接调用int,要用finnal进行变量传参
-
for (int i = 1; i <= 7; i++) { final int temp = i; new Thread(()->{ System.out.println(temp); try { } },String.valueOf(i)).start();
-
3、Semaphore——信号量
-
使用方法:
semaphore.acquire();//得到(占位),假设如果已经满了,等待被释放 semaphore.release();//释放(让位),将当前的位置让出
-
作用:多个共享资源互斥的使用!并发限流,控制最大的线程数!
-
形象记忆:看下面案例!最大限流抢车位!
-
代码案例:
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);//限流时候用,创建最大存在车位数量
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
semaphore.acquire();//得到车位
System.out.println(Thread.currentThread().getName()+"抢到车位");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//释放车位
}
}).start();
}
}
}