问题
This super simple application prints "Hello" but does not finish. I see absolutely no reason why this should be.
JavaDoc, section finalization, says that
A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically.
tpe
is clearly not referenced, that means that thread does not finish. But I don't understand why. Could someone explain?
Solution in this case is to call shutdown() at the end of main, but my actual application is more complicated. New work is generated inside of Runnables, so I don't know when exactly everything will be processed.
So, do I need to figure out when to call shutdown? Or is it possible to somehow specify that, when tpe
's queue is empty, it should shut itself down?
public class JavaApplication5 {
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(5, 15, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
tpe.execute(new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
});
}
}
回答1:
When your main method finishes your executor has no tasks left, but it still has threads running.
Set the flag allowCoreThreadTimeout to true before submitting any tasks. Then when your executor goes out of scope as the main method finishes, and all your tasks finish, the threads will be terminated. See Finalization in the ThreadPoolExecutor API documentation:
A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed even if users forget to call shutdown(), then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or setting allowCoreThreadTimeOut(boolean).
回答2:
Or is it possible to somehow specify, that when tpe's queue is empty, than shutdown itself? - No. Even if it was possible, the tpe's queue would be empty when you create the object at first and so would shutdown.
But you can use the ThreadPoolExecutor.getActiveCount()
to get an idea of how many threads are currently running. If it reaches 0 and stays there for sometime, you can shutdown the executor.
来源:https://stackoverflow.com/questions/30633698/threadpoolexecutor-application-does-not-finish