引言
高并发现如今是面试无可避免的一道关卡,在大家都准备好的面前得会一些必杀技(亮点),下面讲的这三个辅助类,在工作中会经常用到,成为自己得一个面试亮点。
三个类得简单介绍
- 加法计数器:一直累加到设置得值,才会放行await,例子:七龙珠,召唤神龙
- 减法计数器: 一直减,直到默认值为0,才会放行await,例子:下班最后一个人关门,秦统一六国
- 信号量: 同步资源,满足设置得数量得线程,然后才会开始释放空间,例子:占车位
JFCount.java(加法计数器)
package 加法计数器;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class JFCount {
public static void main(String[] args) {
// TODO 自动生成的方法存根
CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{
System.out.println("集齐7颗龙珠,召唤神龙!");
});
for(int i=1;i<=7;i++) {
final int temp=i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t收集到第"+String.valueOf(temp)+"龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} //开始加
},String.valueOf(i)) .start();
}
}
}
输出结果
1 收集到第1龙珠
3 收集到第3龙珠
2 收集到第2龙珠
4 收集到第4龙珠
6 收集到第6龙珠
5 收集到第5龙珠
7 收集到第7龙珠
集齐7颗龙珠,召唤神龙!
AddCount.java(减法计数器)
package 减法计数器;
import java.util.concurrent.CountDownLatch;
public class AddCount {
public static void main(String[] args) throws Exception {
// TODO 自动生成的方法存根
CountDownLatch countDownLatch=new CountDownLatch(6);
for(int i=1;i<=6;i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t被灭亡");
countDownLatch.countDown(); //开始加
},CountEnum.forEach_ConuntryEnum(i).getRetMessage()) .start(); //利用枚举改写线程名字,减少代码耦合,便于修改
}
countDownLatch.await(); //锁住了main线程然后只有等到加法计数器达到6结束
System.out.println(Thread.currentThread().getName()+"\t秦国一统天下");
}
}
CountEnum.java(线程名)
package 减法计数器;
public enum CountEnum {
ONE(1,"齐"),TWO(2,"楚"),THREE(3,"燕"),FOUR(4,"赵"),Five(5,"魏"),SIX(6,"韩");
private Integer retCode;
private String retMessage;
private CountEnum(Integer retCode, String retMessage) {
this.retCode = retCode;
this.retMessage = retMessage;
}
public static CountEnum forEach_ConuntryEnum(int index) {
CountEnum[] myArray=CountEnum.values();
for(CountEnum element:myArray) {
if(index==element.getRetCode()) {
return element;
}
}
return null;
}
public Integer getRetCode() {
return retCode;
}
public void setRetCode(Integer retCode) {
this.retCode = retCode;
}
public String getRetMessage() {
return retMessage;
}
public void setRetMessage(String retMessage) {
this.retMessage = retMessage;
}
}
输出结果
齐 被灭亡
楚 被灭亡
燕 被灭亡
赵 被灭亡
魏 被灭亡
韩 被灭亡
main 秦国一统天下
Semaphore1.java(信号量)
同步方法
package 信号量;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class Semaphore1 {
///互斥资源,同步方法
public static void main(String[] args) {
// TODO 自动生成的方法存根
Semaphore semaphore=new Semaphore(3);
for(int i=0;i<6;i++) {
new Thread(()->{
try {
semaphore.acquire(); //加锁
System.out.println(Thread.currentThread().getName()+"停车3秒后离开");
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
semaphore.release(); //释放
}
},String.valueOf(i)).start();
}
}
}
输出结果
0停车3秒后离开
1停车3秒后离开
2停车3秒后离开
//这里会睡眠3秒之后才有后面三辆车
4停车3秒后离开
5停车3秒后离开
3停车3秒后离开
//3秒后全离开了
总结
- 手敲一遍便于理解和记忆
- 重要是学会使用辅助类可以调度线程,避免频繁加锁解锁