ConcurrentLinkedQueue和线程结合使用

ConcurrentLinkedQueue 是非阻塞队列
概念
并编程中,一般需要用到安全的队列,如果要自己实现安全队列,可以使用2种方式:
方式1:加锁,这种实现方式就是我们常说的阻塞队列。
方式2:使用循环CAS算法实现,这种方式实现队列称之为非阻塞队列。
非阻塞队列经典实现类:ConcurrentLinkedQueue (JDK1.8版)

业务场景:
审批流程:
当发起审批流程时,需要调用钉钉接口,钉钉接口推送任务给用户,用户审批。
调用钉钉接口时耗费的时间比较长,所以把调用接口这块放到ConcurrentLinkedQueue这里实现。
先把审批流程的id通过add放到队列里,然后在用异步线程去队列里取出id,然后再调用钉钉接口。
以下是我的实现的类:
我的项目是基于srpingboot。
实现步骤如下:
1.写一个线程类TaskThread继承Thread。这个类是启动线程,从队列里取出数据执行。
2.在springboot启动类去启动这个TaskThread类。
3.创建一个任务类Task,里面只有一个run方法。这个类的作用是便于具体实现类来继承。
4.再创建一个具体实现的任务类ProcessTask,来实现run方法,在这里写具体的操作。
5.在controlloer里具体使用的类DingTalkController。
代码如下:

**import java.util.concurrent.ConcurrentLinkedQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component(value = "taskThread")
public class TaskThread extends Thread{
    Logger logger = LoggerFactory.getLogger(TaskThread.class);
    private ConcurrentLinkedQueue<Task> taskQueue;
    private boolean _stop = false;
    public TaskThread(){
        taskQueue = new ConcurrentLinkedQueue<>();
    }
    public void addTask(Task task){
        taskQueue.add(task);
    }
    public void setStop(){
        synchronized (taskQueue){
            _stop = true;
            taskQueue.notify();
        }
    }
    @Override
    public void run(){
        logger.info("线程已启动");
        synchronized (taskQueue){
            while (!_stop){
                if(!taskQueue.isEmpty()){
                    Task task = taskQueue.poll();
                    if(task != null){
                        try{
                            task.run();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }else {
                        try {
                            taskQueue.wait(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }**
public class WsqfApplication {
    public static ConfigurableApplicationContext applicationContext;
    public static void main(String[] args) {
        applicationContext = SpringApplication.run(WsqfApplication.class, args);
        //开启线程
        TaskThread taskThread = (TaskThread) applicationContext.getBean("taskThread");
        taskThread.start();
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.thunisoft.wsqf.controller.WsqfController;
import com.thunisoft.wsqf.dingtalk.service.DingTalkService;
import com.thunisoft.wsqf.utils.BaseResult;

@Component("processTask")
@Scope("prototype") //表示每次获得bean都会生成一个新的对象
public class ProcessTask implements Task {
    Logger logger = LoggerFactory.getLogger(ProcessTask.class);
    @Autowired
    private WsqfController wsqfController;

    @Autowired
    private DingTalkService dingTalkService;

    private String taskId;
    private String type;

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public void run() {
        try{
            logger.info("流程任务start_"+this.getTaskId());
            String processId = this.getTaskId();
            JSONObject paramJson = new JSONObject();
            paramJson.put("processId", processId);
            getUnfinishProcessTask(paramJson,this.getType());
            logger.info("流程任务end_"+this.getTaskId());
        }catch (Exception e){
            //获取代办任务失败,把processId保存到表里
            logger.info(e.getMessage());
        }
    }

    /**
     *获取代办任务
     * @param json
     */
    public void getUnfinishProcessTask(JSONObject json,String type){
        logger.info("内网拉取待办任务:   processId="+json.getString("processId"));
        BaseResult baseResult = wsqfController.apis("lczxTaskList", json.toString());
        if(baseResult.getCode().equals("200")){
            JSONObject data = new JSONObject();
            if(baseResult.getObj() != null){
                data = JSONObject.parseObject(baseResult.getObj().toString());
            }
            if("create".equals(type)) {
                logger.info("钉钉流程begin");
                dingTalkService.dingTalkProcessNotice(json.getString("processId"),data,"start");
                logger.info("钉钉流程end");
            }else {
                logger.info("更新钉钉待办任务begin");
                dingTalkService.dingTalkProcessNotice(json.getString("processId"),data,"update");
                logger.info("更新钉钉待办任务end");
            }
        } else { //如果调用内网失败了保存流程实例id到流程表里
            dingTalkService.insertProcessInfoOne(json.getString("processId"));
        }
    }
}
**@RestController
@RequestMapping("/api/v2/")
public class DingTalkController {
    private static Logger logger = LoggerFactory.getLogger(DingTalkController.class);
    @Autowired
    private TaskThread taskThread;
    @Autowired
    private ProcessTask processTask;
    @PostMapping("dingtalk")
    public BaseResult callDingTalks(@RequestBody JSONObject json) {
        String methodName = json.getString("methodName");
        JSONObject resJson = JSONObject.parseObject(json.getString("data"));
        logger.info("内网应用调用钉钉接口开始。。。。。");
        String processId = resJson.getString("processId");
        if (methodName.equals(DingEnum.createDingTalkProcess.name())) {//开启钉钉流程
            logger.info("内网发送的processId="+processId);
            processTask.setTaskId(processId);
            processTask.setType("create");
            taskThread.addTask(processTask);
            return new BaseResult("200","获取流程实例id成功",null);
        }else if(methodName.equals(DingEnum.updateWorkrecordTask.name())) {//更新钉钉待办任务
            logger.info("内网发送的processId="+processId);
            processTask.setTaskId(processId);
            processTask.setType("update");
            taskThread.addTask(processTask);
            return new BaseResult("200","获取流程实例id成功",null);
        }
        return new BaseResult("500","接收信息出错");
    }
}**
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值