ThreadPoolTask​​Executor关闭/重新运行问题

时间:2015-12-23 13:38:29

标签: java multithreading spring java.util.concurrent

我尝试使用Spring的ThreadPoolTask​​Executor'来实现多线程持续任务执行。

以下是我的课程:

@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启动线程的用户的用户名。)可以吗?

2 个答案:

答案 0 :(得分:0)

一旦任务完成了工作,它们就不再存在,您需要将它们重新提交给调度程序才能让它们再次运行。他们不会无限期地留在遗嘱执行人之内。

答案 1 :(得分:0)

这可能是一个时间问题。尝试添加一个短暂的等待,如

Thread.sleep(1000); 

之前

System.out.println("Active threads: " +executor.getActiveCount());

并尝试写出池大小(以确定池大小是否设置正确):

System.out.println("Active threads: " +executor.getPoolSize());