我尝试使用Spring的ThreadPoolTaskExecutor'来实现多线程持续任务执行。
以下是我的课程:
@Component
public class AsyncWorker implements Worker {
public int threadCount = 5;
private ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
@Async
public void doWork(Runnable runnable){
executor.initialize();
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setCorePoolSize(threadCount);
executor.setMaxPoolSize(threadCount);
executor.setQueueCapacity(0);
executor.setThreadGroupName("A");
for (int i=0;i<5;i++) {
executor.submit(runnable);
}
System.out.println("Active threads: " +executor.getActiveCount());
}
@Async
public void StopTasks(){
executor.shutdown();
}
用法:
@Controller
@RequestMapping("api/test")
public class SendController {
ThreadPoolExecutor executor = new ErrorReportingThreadPoolExecutor(5);
@Autowired AsyncWorker worker;
boolean IsRunning = true;
@RequestMapping(value = "/start_new", method = RequestMethod.POST)
public Callable<String> StartNewTask(@RequestBody LaunchSend sendobj) throws IOException, InterruptedException {
// System.out.println(sendobj.getThreadsCount());
Runnable runnable = () -> {
while(IsRunning) {
MyVoid();
}
};
worker.doWork(runnable);
return () -> "Callable result";
}
@RequestMapping(value = "/stop", method = RequestMethod.GET)
public Callable<String> StopTasks() {
IsRunning =false;
if(SecurityContextHolder.getContext().getAuthentication().getName() != null && SecurityContextHolder.getContext().getAuthentication().getName() != "anonymousUser") {
worker.StopTasks();
return () -> "Callable result good";
}
else { return () -> "Callable result bad";}
}
}
主要问题是:
当我第一次发送开始请求时 - 一切正常(除非我没有看到组名称的变化(executor.setThreadGroupName(&#34; A&#34;))。) / p>
但是,在我发送停止请求并再次发送启动请求之后 - 执行程序没有启动任务。这是它的样子:
ThreadPoolTaskExecutor-4 Global iteration # 4
ThreadPoolTaskExecutor-2 Global iteration # 5
ThreadPoolTaskExecutor-5 Global iteration # 3
ThreadPoolTaskExecutor-3 Global iteration # 2
Active threads: 5
ThreadPoolTaskExecutor-1 Global iteration # 1
ThreadPoolTaskExecutor-2 Global iteration # 9
ThreadPoolTaskExecutor-3 Global iteration # 9
ThreadPoolTaskExecutor-5 Global iteration # 9
ThreadPoolTaskExecutor-4 Global iteration # 9
ThreadPoolTaskExecutor-1 Global iteration # 10
Active threads: 1
只显示&#34;活动线程:1&#34;。可能有什么问题?
顺便说一下,将来,我想为它创建的ThreadGroup设置自定义名称(从POST请求/ Spring安全上下文转移的param),然后能够终止所有带有某个组名的线程(组名将是Spring Security启动线程的用户的用户名。)可以吗?
答案 0 :(得分:0)
一旦任务完成了工作,它们就不再存在,您需要将它们重新提交给调度程序才能让它们再次运行。他们不会无限期地留在遗嘱执行人之内。
答案 1 :(得分:0)
这可能是一个时间问题。尝试添加一个短暂的等待,如
Thread.sleep(1000);
之前
System.out.println("Active threads: " +executor.getActiveCount());
并尝试写出池大小(以确定池大小是否设置正确):
System.out.println("Active threads: " +executor.getPoolSize());