利用单线程池实现一个任务队列demo
基本思路:新任务来了,就把任务放到队列里面,然后利用单线程从里面取,一个个执行,用于一些比较特殊的应用场景。
controller模拟前端发起任务请求
@RestController
public class MySafeQueueController {
@Autowired
MySafeQueueService mySafeQueueService;
@PostMapping("addToQueue")
public void addToQueue(@RequestBody String user) {
mySafeQueueService.addToQueue(user);
}
@GetMapping("showQueueStatus")
public void showQueueStatus() {
mySafeQueueService.showQueueStatus();
}
}
service实现
import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Service;
import java.util.Iterator;
import java.util.concurrent.*;
/**
* @author: csl
* @description:
* @date: 2021-03-05 22:29
*/
@Service
public class MySafeQueueService {
/**
* 单线程,每次从队列任务中去一个任务执行
*/
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
/**
* 测试加入队列的方法
*
* @param user 用户
*/
public void addToQueue(String user) {
User userJson = JSON.parseObject(user, User.class);
System.out.println("接收到 " + userJson.getUsername() + " 的请求,开始入队");
try {
//将任务添加到队列里面,我这里就添加一个对象进去测试
//添加失败抛出异常
ConstantUtil.linkedBlockingQueue.add(userJson);
} catch (Exception e) {
throw new RuntimeException("队列已满,请稍后在添加任务");
}
MySingleThreadRunnable runnable = new MySingleThreadRunnable();
//Future<?> submit = singleThreadExecutor.submit(runnable); 可获得返回结果,有需要就用
singleThreadExecutor.submit(runnable);
System.out.println(userJson.getUsername() + "任务已经安排了,在异步进行处理了");
}
/**
* 查看队列里面剩余的任务个数
*/
public void showQueueStatus() {
System.out.println(ConstantUtil.linkedBlockingQueue);
Iterator<User> iterator = ConstantUtil.linkedBlockingQueue.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
MySingleThreadRunnable实现
public class MySingleThreadRunnable implements Runnable {
@Override
public void run() {
while (!ConstantUtil.linkedBlockingQueue.isEmpty()) {
try {
User take = ConstantUtil.linkedBlockingQueue.take();
System.out.println("取出了 " + take.getUsername());
//延时,模拟任务会执行一会儿
Thread.sleep(10 * 1000);
System.out.println(take.getUsername() + " 执行完毕---");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//这里的代码会执行很多次
}
}
任务队列
public class ConstantUtil {
/**
* 存放任务的队列
*/
public static LinkedBlockingQueue<User> linkedBlockingQueue = new LinkedBlockingQueue<>(5);
}
用postman发请求测试结果大概如下
这个小demo只是自己平时做个笔记,欢迎大佬指正。