ScheduledExecutorService 如何处理终止的线程?
How does ScheduledExecutorService handles terminated threads?
ScheduledExecutorService
是否负责处理终止线程并生成新线程?
在下面的示例中,如果我的任何一个线程由于 Error
而终止,线程池大小会发生什么变化?
调试时,我注意到此服务创建的其中一个线程在未打印任何日志语句的情况下被静默终止。在检查线程转储时,我仍然可以看到 32 个线程仍然存在,其中 none 个被阻塞。
public class CacheManager
{
private static class CacheRefresher extends Thread
{
Cache cache;
public CacheRefresher(Cache cache)
{
this(cache);
}
@Override
public final void run()
{
try {
LOG.info("cache is getting refreshed for " + cache.type);
cache.refreshCache();
} catch (Exception e) {
String subject = "Cache refresh failed in BMW";
LOG.log(Level.WARN, subject + ". Exception thrown:", e);
}
}
}
public void refreshCaches(List<cache> caches)
{
ThreadFactory ourThreadFactory =
new NamedThreadFactory("CacheHandler", true);
ScheduledExecutorService scheduleService =
Executors.newScheduledThreadPool(32, ourThreadFactory);
initialDelay = 60;
for (Cache cache : caches) {
service.scheduleWithFixedDelay(new CacheRefresher(cache), initialDelay, 20, TimeUnit.SECONDS);
initialDelay += 2;
cacheContainers.add(cache);
}
}
}
正如在 Javadoc newScheduledThreadPool(int) 中找到的那样,总是会有指定数量的线程。即使一个线程将关闭,也会启动另一个线程。 但首先,ScheduledExecutorService
内的线程应该被重用,即使在 Runnable.run()
.
内发生异常时也是如此
并确保线程没有被阻塞,而是在等待新的操作...
虽然 Executors.newFixedThreadPool 的 JavaDocs 明确提到了这一点:
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
关于 Executors.newScheduledThreadPool 没有如此有力的保证。
它在这方面的行为可能相同,但这是您不需要关心的实现细节。 Executor 服务将 provide/create 足够的线程来执行给定的任务。
计划任务中未捕获的异常不会导致计划程序的线程终止。但是,它将阻止失败的任务成为 re-scheduled。请参阅 ScheduledThreadPoolExecutor.html#scheduleWithFixedDelay 的相应文档:
The sequence of task executions continues indefinitely until one of the following exceptional completions occur:
[...]
An execution of the task throws an exception. In this case calling get on the returned future will throw ExecutionException, holding the exception as its cause.
ScheduledExecutorService
是否负责处理终止线程并生成新线程?
在下面的示例中,如果我的任何一个线程由于 Error
而终止,线程池大小会发生什么变化?
调试时,我注意到此服务创建的其中一个线程在未打印任何日志语句的情况下被静默终止。在检查线程转储时,我仍然可以看到 32 个线程仍然存在,其中 none 个被阻塞。
public class CacheManager
{
private static class CacheRefresher extends Thread
{
Cache cache;
public CacheRefresher(Cache cache)
{
this(cache);
}
@Override
public final void run()
{
try {
LOG.info("cache is getting refreshed for " + cache.type);
cache.refreshCache();
} catch (Exception e) {
String subject = "Cache refresh failed in BMW";
LOG.log(Level.WARN, subject + ". Exception thrown:", e);
}
}
}
public void refreshCaches(List<cache> caches)
{
ThreadFactory ourThreadFactory =
new NamedThreadFactory("CacheHandler", true);
ScheduledExecutorService scheduleService =
Executors.newScheduledThreadPool(32, ourThreadFactory);
initialDelay = 60;
for (Cache cache : caches) {
service.scheduleWithFixedDelay(new CacheRefresher(cache), initialDelay, 20, TimeUnit.SECONDS);
initialDelay += 2;
cacheContainers.add(cache);
}
}
}
正如在 Javadoc newScheduledThreadPool(int) 中找到的那样,总是会有指定数量的线程。即使一个线程将关闭,也会启动另一个线程。 但首先, ScheduledExecutorService
内的线程应该被重用,即使在 Runnable.run()
.
并确保线程没有被阻塞,而是在等待新的操作...
虽然 Executors.newFixedThreadPool 的 JavaDocs 明确提到了这一点:
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
关于 Executors.newScheduledThreadPool 没有如此有力的保证。
它在这方面的行为可能相同,但这是您不需要关心的实现细节。 Executor 服务将 provide/create 足够的线程来执行给定的任务。
计划任务中未捕获的异常不会导致计划程序的线程终止。但是,它将阻止失败的任务成为 re-scheduled。请参阅 ScheduledThreadPoolExecutor.html#scheduleWithFixedDelay 的相应文档:
The sequence of task executions continues indefinitely until one of the following exceptional completions occur:
[...]
An execution of the task throws an exception. In this case calling get on the returned future will throw ExecutionException, holding the exception as its cause.