springboot请求排队处理

spingboot 并发请求下排队一个个"就诊"

有一个需求:编写一个接口 这个接口打开本地的notepad记事本,允许并发
如果单纯的写一个接口,并发下是会有问题的,因为notepad已经被第一个请求先打开了,后续请求都返回失败,如果我想每个请求都能打开成功,notepad被别的请求打开了那就阻塞等待直到关闭notepad。
类似医生一次就诊一个病人,病人抽号排队看病。

技术实现
阻塞队列+单例线程池

代码如下
实现Callable接口,这个接口有返回值

核心代码

package com.bim.task;


import com.bim.pojo.ConvertObj;
import com.bim.service.TransServiceImpl;
import com.bim.utils.Result;
import com.bim.utils.SpringUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author gaoye
 * @date 2022/2/16 11:50
 * @desc 远程启动
 */
@Data
@Slf4j
public class StartTask implements Callable {
    # 1.阻塞队列 一次一个任务
    public static LinkedBlockingDeque linkBlockQueue = new LinkedBlockingDeque<>(1);

    public StartTask(ConvertObj convertObj) {
        try {
          #2.  put的时候 容量满了就阻塞  我设置了1个实现了排队进行
            linkBlockQueue.put(convertObj);
            log.info("当前队列值数量:" + linkBlockQueue.size());
        } catch (InterruptedException e) {
            log.info(e.getMessage());
        }
    }
    
    @Override
    public Result call() {
        Result result;
        try {
          #3. submit后会执行我的业务
            TransServiceImpl transService = SpringUtils.getBean("transServiceImpl");
            #读取入栈的值 但没移除掉  
            ConvertObj convertObj = linkBlockQueue.peek();
            #执行业务逻辑
            result = transService.convert(convertObj.getHttpServl etRequest(), convertObj.getMultipartFile());
            # 4. 移除队列首值也是唯一的值  被阻塞的请求可以put了 也就是第2步骤可以跑了
            linkBlockQueue.take();

        } catch (Exception e) {
            try {
              # 抛出异常也要去除掉,要不然以后没法put进去 服务就废了
                linkBlockQueue.take();
            } catch (InterruptedException ex) {
                log.info(ex.getMessage());
            }
            log.error(e.getMessage());
            return Result.fail(e.getMessage());
        }
        return result;
    }

}

提交任务

#单例线程池
 public static final ExecutorService threadPool = Executors.newSingleThreadExecutor();

#提交任务
        StartTask startTask=new StartTask(convertObj);
        Future future = threadPool.submit(startTask);
        Result result = future.get();

如果你有更好的方法,请留言 或加qq:1129174385

你可能感兴趣的:(spring,boot,java,后端)