Reputation: 1
Here is some main code of my question,I'm a Student in China,My English is not good, please the excuse me.
public static void main(String[] args) {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Thread-%d").build();
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
5, 10, 0, TimeUnit.SECONDS, new SynchronousQueue<>(),
threadFactory, new ThreadPoolExecutor.DiscardPolicy()
);
// I submit 10 short task here
// 👇I want when ThreadPool finish 10 task, then shut down the pool👇
while (!poolExecutor.isTerminated() && poolExecutor.getCompletedTaskCount() == 10) {
poolExecutor.shutdown();
}
}
I want when ThreadPool finish 10th task, then shut down the pool,but the while loop does not seems to execute,the main Thread has been finished,but the core Thread of ThreadPool is still Waiting for task。
If I do not use the while
loop and directly use poolExecutor.shutdown();
. I can get the expected results. All the threads are finished and shutdown correctly.
But I want to know what's the error of my code.
Upvotes: 0
Views: 259
Reputation: 339472
Call close
in Java 19+.
shutdownAndAwaitTermination
boilerplateIn Java 5+, you can use the boilerplate code named shutdownAndAwaitTermination
given in the Javadoc for ExecutorService
.
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ex) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
ExecutorService#close
Or, in Java 19+, call close
.
See the source code at OpenJDK.
@Override
default void close() {
boolean terminated = isTerminated();
if (!terminated) {
shutdown();
boolean interrupted = false;
while (!terminated) {
try {
terminated = awaitTermination(1L, TimeUnit.DAYS);
} catch (InterruptedException e) {
if (!interrupted) {
shutdownNow();
interrupted = true;
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
Tip: Unless you have a special need, use Executors
utility class to instantiate an ExecutorService
.
Upvotes: 2
Reputation: 1
I have solved my question, It just a logic error, Sorry waste everyone's time, the correct code is that:
public static void main(String[] args) {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Thread-%d").build();
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
5, 10, 0, TimeUnit.SECONDS, new SynchronousQueue<>(),
threadFactory, new ThreadPoolExecutor.DiscardPolicy()
);
while (!poolExecutor.isTerminated()) {
if (poolExecutor.getCompletedTaskCount() == 10) {
poolExecutor.shutdown();
}
}
}
If I use the logical expression !poolExecutor.isTerminated() && poolExecutor.getCompletedTaskCount() == SORT_ALGORITHM_SIZE
in while loop, It will probably beacause true && false
and exit the loop. Then I can't close the thread pool
Thank you again for your help.
Upvotes: 0
Reputation:
There might be some issues with the getCompletedTaskCount
method, but I'm not sure. I do know, that the suggested method of shutting down (and waiting for the imminent termination of) a ThreadPool is the following:
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Thread-%d").build();
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
5, 10, 0, TimeUnit.SECONDS, new SynchronousQueue<>(),
threadFactory, new ThreadPoolExecutor.DiscardPolicy()
);
// submit to poolExecutor
poolExecutor.shutdown();
// This is where the magic happens:
// maxTimeToWait is the amount of unitOfTimes to wait at max, before just continuing.
// javadoc: Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
poolExecutor.awaitTermination(maxTimeToWait, unitOfTime);
Upvotes: 0