记录一个LinkedBlockingDeque的简单应用

背景:在某产品代码,有事件生成的时候会生成一个事件id,产品会拿事件id进行后面的一系列的逻辑处理。

需求:现在有另外一个需求,也要拿到每一次的事件id,然后在另一个类中处理其他的逻辑。由于原来的逻辑处理较多,新需求只能尽量减少对原代码的嵌入。

思路:创建一个类来处理新需求,这个类提供一个方法A()把事件id存到队列中,在原来产品的代码只需要调A()方法把事件id存到队列,然后就可以在新类中进行逻辑处理。

LinkedBlockingDeque简单介绍( 本文只是简单记录一次使用)

  • LinkedBlockingDeque是一个由链表结构组成的双向阻塞队列,即可以从队列的两端插入和移除元素。
  • 相比于其他阻塞队列,LinkedBlockingDeque多了addFirst、addLast、peekFirst、peekLast等方法
  • LinkedBlockingDeque是可选容量的,默认容量大小为Integer.MAX_VALUE。

使用过程

1.先创建一个CommenServiceImpl类,作为处理新需求的类

@Service("GtmcCommenServiceImpl")
public class CommenServiceImpl{

//省略

}

2.创建LinkedBlockingDeque对象incidentIdList,并新加一个方法来实现往incidentIdList添加事件id

final static BlockingDeque<String> incidentIdList = new LinkedBlockingDeque<>();
private volatile Thread thread = null;
//当有事件id添加成功后,起一个线程单独处理新的逻辑
public void SetIncidentIdList(String incidentId) {
    if (null == incidentId || "".equals(incidentId.trim())) {
        return;
    }
    incidentIdList.offer(incidentId);
    log.info("事件id入List成功:" + incidentId);
    if (thread == null) {
        thread = new Thread(this::setAlarm);
        thread.start();
    }
    if(!thread.isAlive() || thread.isInterrupted()){
        thread = new Thread(this::setAlarm);
        thread.start();
    }
}

 3.在原来生成事件id的产品代码注入CommenServiceImpl,然后通过SetIncidentIdList方法添加事件id到LinkedBlockingDeque

gtmcCommenService.SetIncidentIdList(incidentId);

 

 4.在新创建的CommenServiceImpl类处理新的需求逻辑

@Slf4j
@Service("CommenServiceImpl")
public class CommenServiceImpl {
    protected static ElasticsearchService elasticsearchService;
    @org.springframework.beans.factory.annotation.Value("${douc.ex.accountId}")
    private String accountId;
    @Autowired
    private IncidentService incidentService;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    @Autowired
    protected EsQueryCreator queryCreator;
    final static BlockingDeque<String> incidentIdList = new LinkedBlockingDeque<>();
  
    private volatile Thread thread = null;

    public GtmcCommenServiceImpl() {
        elasticsearchService = ElasticsearchService.getInstance();
    }

    /**
     * 新起一个线程循环处理
     */
    void setAlarm() {
        while (true) {
            try {
                List<String> list = new LinkedList<>();
                incidentIdList.drainTo(list,20);//一次最多从incidentIdList拿20个出来
                for (String evenId : list) {
                    

                   //省略逻辑处理代码



                    kafkaTemplate.send(TOPIC, JSONObject.toJSONString(map));
                    
                }
            } catch (Exception e) {
                log.error("监控告警生成和解决,发送事件id和配置项id给kafka发生错误 {}" + (e));
            }
        }
    }

    public void SetIncidentIdList(String incidentId) {
        if (null == incidentId || "".equals(incidentId.trim())) {
            return;
        }
        incidentIdList.offer(incidentId);
        log.info("事件id入List成功:" + incidentId);
        if (thread == null) {
            thread = new Thread(this::setAlarm);
            thread.start();
        }
        if(!thread.isAlive() || thread.isInterrupted()){
            thread = new Thread(this::setAlarm);
            thread.start();
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值