How can a threadpool be reused after shutdown

后端 未结 3 894
走了就别回头了
走了就别回头了 2020-12-14 00:26

I have a .csv file containing over 70 million lines of which each line is to generate a Runnable and then executed by threadpool. This Runnable will insert

相关标签:
3条回答
  • 2020-12-14 00:27

    After calling shutdown on a ExecutorService, no new Task will be accepted. This means you have to create a new ExecutorService for each round of tasks.

    However, with Java 8 ForkJoinPool.awaitQuiescence was introduced. If you can switch from a normal ExecutorService to ForkJoinPool, you can use this method to wait until no more tasks are running in a ForkJoinPool without having to call shutdown. This means you can fill a ForkJoinPool with Tasks, waiting until it is empty (quiescent), and then again begin filling it with Tasks, and so on.

    0 讨论(0)
  • 2020-12-14 00:40

    create and group all tasks and submit them to the pool with invokeAll (which only returns when all tasks are successfully completed)

    0 讨论(0)
  • 2020-12-14 00:53

    As stated in the documentation, you cannot reuse an ExecutorService that has been shut down. I'd recommend against any workarounds, since (a) they may not work as expected in all situations; and (b) you can achieve what you want using standard classes.

    You must either

    1. instantiate a new ExecutorService; or

    2. not terminate the ExecutorService.

    The first solution is easily implemented, so I won't detail it.

    For the second, since you want to execute an action once all the submitted tasks have finished, you might take a look at ExecutorCompletionService and use it instead. It wraps an ExecutorService which will do the thread management, but the runnables will get wrapped into something that will tell the ExecutorCompletionService when they have finished, so it can report back to you:

    ExecutorService executor = ...;
    ExecutorCompletionService ecs = new ExecutorCompletionService(executor);
    
    for (int i = 0; i < totalTasks; i++) {
      ... ecs.submit(...); ...
    }
    
    for (int i = 0; i < totalTasks; i++) {
      ecs.take();
    }
    

    The method take() on the ExecutorCompletionService class will block until a task has finished (either normally or abruptly). It will return a Future, so you can check the results if you wish.

    I hope this can help you, since I didn't completely understand your problem.

    0 讨论(0)
提交回复
热议问题