Execute a continious task via ThreadPoolExecutor

試著忘記壹切 提交于 2019-12-12 05:40:15

问题


Facing the problem with the ThreadPoolExecutor in Java.

How can I execute a continuous task using it? For example, I want to execute something like this:

    @Async
    void MyVoid(){
       Globals.getInstance().increment();
       System.out.println(Thread.currentThread().getName()+" iteration # "+ Globals.getInstance().Iterator);
    }

I want it to run forever in 2 parallel asynchronous threads until the user sends a request to stop the ThreadPoolExecutor in the "/stop" controller.

If I use this for example:

    @Controller
    @RequestMapping("api/test")
    public class SendController {

        ThreadPoolExecutor executor =  new ErrorReportingThreadPoolExecutor(5);
        boolean IsRunning = true;

        @RequestMapping(value = "/start_new", method = RequestMethod.POST)
        public Callable<String> StartNewTask(@RequestBody LaunchSend sendobj) throws IOException, InterruptedException {

            Runnable runnable = () -> { MyVoid();};
            executor.setCorePoolSize(2);
            executor.setMaximumPoolSize(2);


            while (IsRunning) {
                executor.execute(runnable);
                System.out.println("Active threads: " + executor.getActiveCount());
            }


            return () -> "Callable result";
        }

        @RequestMapping(value = "/stop", method = RequestMethod.GET)
        public Callable<String> StopTasks()  {
            executor.shutdown(); //for test
            if(SecurityContextHolder.getContext().getAuthentication().getName() != null &&  SecurityContextHolder.getContext().getAuthentication().getName() != "anonymousUser") {
                executor.shutdown();
                return () -> "Callable result good";
            }
            else { return () -> "Callable result bad";}
        }
    }

public class ErrorReportingThreadPoolExecutor extends ThreadPoolExecutor {
    public ErrorReportingThreadPoolExecutor(int nThreads) {
        super(nThreads, nThreads,
                0, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());
    }

    @Override
    protected void afterExecute(Runnable task, Throwable thrown) {
        super.afterExecute(task, thrown);

        if (thrown != null) {
            // an unexpected exception happened inside ThreadPoolExecutor
            thrown.printStackTrace();
        }

        if (task instanceof Future<?>) {
            // try getting result
            // if an exception happened in the job, it'll be thrown here
            try {
                Object result = ((Future<?>)task).get();
            } catch (CancellationException e) {
                // the job get canceled (may happen at any state)
                e.printStackTrace();
            } catch (ExecutionException e) {
                // some uncaught exception happened during execution
                e.printStackTrace();
            } catch (InterruptedException e) {
                // current thread is interrupted
                // ignore, just re-throw
                Thread.currentThread().interrupt();
            }
        }
    }
}

I'm getting the following errors:

  1. As I understood, a lot of tasks got submitted into the 'executor' queue within a few seconds and then the executor handled all them. (But I need each thread to wait before the current task ends and then submit the new one to the executor, I think.)

  2. HTTP Requests to these controllers are forever "IDLE" until the next request comes, i.e. after sending a request to /api/test/start_new the controller's code executed tasks that are running, but the request is IDLE.

How can I do this in Java?

P.S. Spring MVC is used in the project. It has its own implementation of ThreadPoolExecutor - ThreadPoolTaskExecutor, but I am facing similar problems with it.

来源:https://stackoverflow.com/questions/34423618/execute-a-continious-task-via-threadpoolexecutor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!