|
|
@ -31,9 +31,8 @@ import java.util.List;
|
|
|
|
import java.util.concurrent.*;
|
|
|
|
import java.util.concurrent.*;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* After the thread pool calls {@link ThreadPoolExecutor#shutdown()} or {@link ThreadPoolExecutor#shutdownNow()},
|
|
|
|
* <p>After the thread pool calls {@link ThreadPoolExecutor#shutdown()} or {@link ThreadPoolExecutor#shutdownNow()}. <br />
|
|
|
|
* if necessary, cancel the remaining tasks in the pool,
|
|
|
|
* Cancel the remaining tasks in the pool, then wait for the thread pool to terminate until
|
|
|
|
* and wait for the thread pool to terminate until
|
|
|
|
|
|
|
|
* the blocked main thread has timed out or the thread pool has completely terminated.
|
|
|
|
* the blocked main thread has timed out or the thread pool has completely terminated.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
@Accessors(chain = true)
|
|
|
|
@Accessors(chain = true)
|
|
|
@ -60,12 +59,6 @@ public class ThreadPoolExecutorShutdownPlugin implements ShutdownAwarePlugin {
|
|
|
|
@Setter
|
|
|
|
@Setter
|
|
|
|
public long awaitTerminationMillis;
|
|
|
|
public long awaitTerminationMillis;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* wait for tasks to complete on shutdown
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Setter
|
|
|
|
|
|
|
|
public boolean waitForTasksToCompleteOnShutdown;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Callback before pool shutdown.
|
|
|
|
* Callback before pool shutdown.
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -77,14 +70,13 @@ public class ThreadPoolExecutorShutdownPlugin implements ShutdownAwarePlugin {
|
|
|
|
ExtensibleThreadPoolExecutor dynamicThreadPoolExecutor = (ExtensibleThreadPoolExecutor) executor;
|
|
|
|
ExtensibleThreadPoolExecutor dynamicThreadPoolExecutor = (ExtensibleThreadPoolExecutor) executor;
|
|
|
|
String threadPoolId = dynamicThreadPoolExecutor.getThreadPoolId();
|
|
|
|
String threadPoolId = dynamicThreadPoolExecutor.getThreadPoolId();
|
|
|
|
if (log.isInfoEnabled()) {
|
|
|
|
if (log.isInfoEnabled()) {
|
|
|
|
log.info("Before shutting down ExecutorService" + " '" + threadPoolId + "'");
|
|
|
|
log.info("Before shutting down ExecutorService {}", threadPoolId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Callback after pool shutdown.
|
|
|
|
* Callback after pool shutdown. <br />
|
|
|
|
* if {@link #waitForTasksToCompleteOnShutdown} return {@code true},
|
|
|
|
|
|
|
|
* cancel the remaining tasks,
|
|
|
|
* cancel the remaining tasks,
|
|
|
|
* then wait for pool to terminate according {@link #awaitTerminationMillis} if necessary.
|
|
|
|
* then wait for pool to terminate according {@link #awaitTerminationMillis} if necessary.
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -95,7 +87,7 @@ public class ThreadPoolExecutorShutdownPlugin implements ShutdownAwarePlugin {
|
|
|
|
public void afterShutdown(ThreadPoolExecutor executor, List<Runnable> remainingTasks) {
|
|
|
|
public void afterShutdown(ThreadPoolExecutor executor, List<Runnable> remainingTasks) {
|
|
|
|
if (executor instanceof ExtensibleThreadPoolExecutor) {
|
|
|
|
if (executor instanceof ExtensibleThreadPoolExecutor) {
|
|
|
|
ExtensibleThreadPoolExecutor pool = (ExtensibleThreadPoolExecutor) executor;
|
|
|
|
ExtensibleThreadPoolExecutor pool = (ExtensibleThreadPoolExecutor) executor;
|
|
|
|
if (!waitForTasksToCompleteOnShutdown && CollectionUtil.isNotEmpty(remainingTasks)) {
|
|
|
|
if (CollectionUtil.isNotEmpty(remainingTasks)) {
|
|
|
|
remainingTasks.forEach(this::cancelRemainingTask);
|
|
|
|
remainingTasks.forEach(this::cancelRemainingTask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
awaitTerminationIfNecessary(pool);
|
|
|
|
awaitTerminationIfNecessary(pool);
|
|
|
@ -110,8 +102,7 @@ public class ThreadPoolExecutorShutdownPlugin implements ShutdownAwarePlugin {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public PluginRuntime getPluginRuntime() {
|
|
|
|
public PluginRuntime getPluginRuntime() {
|
|
|
|
return new PluginRuntime(getId())
|
|
|
|
return new PluginRuntime(getId())
|
|
|
|
.addInfo("awaitTerminationMillis", awaitTerminationMillis)
|
|
|
|
.addInfo("awaitTerminationMillis", awaitTerminationMillis);
|
|
|
|
.addInfo("waitForTasksToCompleteOnShutdown", waitForTasksToCompleteOnShutdown);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -139,11 +130,13 @@ public class ThreadPoolExecutorShutdownPlugin implements ShutdownAwarePlugin {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
boolean isTerminated = executor.awaitTermination(this.awaitTerminationMillis, TimeUnit.MILLISECONDS);
|
|
|
|
boolean isTerminated = executor.awaitTermination(this.awaitTerminationMillis, TimeUnit.MILLISECONDS);
|
|
|
|
if (!isTerminated && log.isWarnEnabled()) {
|
|
|
|
if (!isTerminated && log.isWarnEnabled()) {
|
|
|
|
log.warn("Timed out while waiting for executor" + " '" + threadPoolId + "'" + " to terminate.");
|
|
|
|
log.warn("Timed out while waiting for executor {} to terminate.", threadPoolId);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
log.info("ExecutorService {} has been shutdowned.", threadPoolId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (InterruptedException ex) {
|
|
|
|
} catch (InterruptedException ex) {
|
|
|
|
if (log.isWarnEnabled()) {
|
|
|
|
if (log.isWarnEnabled()) {
|
|
|
|
log.warn("Interrupted while waiting for executor" + " '" + threadPoolId + "'" + " to terminate.");
|
|
|
|
log.warn("Interrupted while waiting for executor {} to terminate.", threadPoolId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Thread.currentThread().interrupt();
|
|
|
|
Thread.currentThread().interrupt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|