并发编程的辅助类[必会]
CountDownLatch
- 辅助减法计数器
package com.LYH_JUC;
import java.util.concurrent.CountDownLatch;
public class CountDownLatch_Test {
public static void main(String[] args) throws InterruptedException {
// 辅助减法计数器
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" : 已出房门");
countDownLatch.countDown(); //计数器减1
},String.valueOf(i+1)).start();
}
countDownLatch.await(); //阻塞当前main线程,直到计数器变为0,当前线程才会被唤醒继续往下执行,可能抛出InterruptedException异常
System.out.println("所有人已出房门,关门!");
}
}
CyclicBarrier
- “循环递增加法计数器”
package com.LYH_JUC;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrier_Test {
public static void main(String[] args) {
/**
* 集齐七颗龙珠召唤神龙!
*/
//召唤神龙的线程
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" : 召唤神龙成功!");
}
};
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,runnable);
/*CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println(Thread.currentThread().getName()+" : 召唤神龙成功!");
});*/
for (int i = 0; i < 7; i++) {
final int temp = i+1; //或者 int temp=i+1; 也行lambda表达式里用的外部变量必须是final或者effectively final
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" : 收集了第"+temp+"龙珠");
try {
cyclicBarrier.await(); //等待线程数变为7,才会继续执行runnable线程
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
注意:线程数一定要是计数器N的正整数倍或者说执行
cyclicBarrier.await();
的次数要是计数器N的正整数倍,否则程序会在最后一次循环计数中阻塞。
package com.LYH_JUC;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrier_Test {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" : 召唤神龙成功!");
}
};
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,runnable);
/*CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println(Thread.currentThread().getName()+" : 召唤神龙成功!");
});*/
for (int i = 0; i < 7; i++) {
final int temp = i+1;
new Thread(()->{
for (int i1 = 0; i1 < 2; i1++) {
System.out.println(Thread.currentThread().getName()+" : 收集了第"+temp+"龙珠");
try {
cyclicBarrier.await(); //执行这条语句每7次,就会执行runnable线程一次
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
Semaphore
信号量:PV操作,共享资源互斥的使用,并发限流,控制最大线程数!
package com.LYH_JUC;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class Semaphore_Test {
public static void main(String[] args) {
//线程数量:3个停车位 限流问题
Semaphore semaphore = new Semaphore(3); //默认为不公平,若想要公平,semaphore = new Semaphore(3,true);
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
semaphore.acquire(); //获得许可证
System.out.println(Thread.currentThread().getName()+" : 抢到车位!");
//System.out.println("-----当前估计的正在排队获得许可证的车数量: "+semaphore.getQueueLength());
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+" : 离开车位!");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release(); //归还许可证
}
}).start();
}
}
}