讲一讲高并发常用的三个辅助类

引言

高并发现如今是面试无可避免的一道关卡,在大家都准备好的面前得会一些必杀技(亮点),下面讲的这三个辅助类,在工作中会经常用到,成为自己得一个面试亮点。

三个类得简单介绍

  1. 加法计数器:一直累加到设置得值,才会放行await,例子:七龙珠,召唤神龙
  2. 减法计数器: 一直减,直到默认值为0,才会放行await,例子:下班最后一个人关门,秦统一六国
  3. 信号量: 同步资源,满足设置得数量得线程,然后才会开始释放空间,例子:占车位

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秒后全离开了

总结

  1. 手敲一遍便于理解和记忆
  2. 重要是学会使用辅助类可以调度线程,避免频繁加锁解锁
发布了105 篇原创文章 · 获赞 19 · 访问量 4967

猜你喜欢

转载自blog.csdn.net/jiohfgj/article/details/105034063