Ant*_*tiz 68 java multithreading executorservice threadpool java-threads
我在Java 1.6中使用ExecutoreService,简单地开始
ExecutorService pool = Executors.newFixedThreadPool(THREADS).
Run Code Online (Sandbox Code Playgroud)
当我的主线程完成时(以及线程池处理的所有任务),此池将阻止我的程序关闭,直到我显式调用
pool.shutdown();
Run Code Online (Sandbox Code Playgroud)
我可以避免不得不通过某种方式将此池使用的内部线程管理变为deamon线程来调用它吗?或者我在这里遗漏了一些东西.
Psh*_*emo 94
可能最简单和首选的解决方案是在Marco13的答案中,所以不要被投票差异(我的回答是几年之久)或接受标记所迷惑(它只是意味着我的解决方案适合OP情况而不是最好).
您可以使用ThreadFactory
将Executor中的线程设置为守护进程.这将影响执行程序服务,它也将成为守护程序线程,因此如果没有其他非守护程序线程,它(以及由它处理的线程)将停止.这是一个简单的例子:
ExecutorService exec = Executors.newFixedThreadPool(4,
new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
exec.execute(YourTaskNowWillBeDaemon);
Run Code Online (Sandbox Code Playgroud)
但是如果你想获得执行程序,它将完成任务,并且同时shutdown()
在应用程序完成时自动调用它的方法,你可能想要用Guava 包装你的执行程序MoreExecutors.getExitingExecutorService
.
ExecutorService exec = MoreExecutors.getExitingExecutorService(
(ThreadPoolExecutor) Executors.newFixedThreadPool(4),
100_000, TimeUnit.DAYS//period after which executor will be automatically closed
//I assume that 100_000 days is enough to simulate infinity
);
//exec.execute(YourTask);
exec.execute(() -> {
for (int i = 0; i < 3; i++) {
System.out.println("daemon");
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Run Code Online (Sandbox Code Playgroud)
Mar*_*o13 46
已经存在一个内置功能,用于创建ExecutorService
在一段时间不活动后终止所有线程:您可以创建一个ThreadPoolExecutor
,传递所需的时间信息,然后调用allowCoreThreadTimeout(true)
此执行器服务:
/**
* Creates an executor service with a fixed pool size, that will time
* out after a certain period of inactivity.
*
* @param poolSize The core- and maximum pool size
* @param keepAliveTime The keep alive time
* @param timeUnit The time unit
* @return The executor service
*/
public static ExecutorService createFixedTimeoutExecutorService(
int poolSize, long keepAliveTime, TimeUnit timeUnit)
{
ThreadPoolExecutor e =
new ThreadPoolExecutor(poolSize, poolSize,
keepAliveTime, timeUnit, new LinkedBlockingQueue<Runnable>());
e.allowCoreThreadTimeOut(true);
return e;
}
Run Code Online (Sandbox Code Playgroud)
编辑参考注释中的注释:请注意,当应用程序退出时,此线程池执行程序不会自动关闭.执行程序将在应用程序退出后继续运行,但不会超过
keepAliveTime
.如果,根据精确的应用程序要求,keepAliveTime
必须超过几秒钟,Pshemo的答案中的解决方案可能更合适:当线程设置为守护程序线程时,它们将在应用程序退出时立即结束.
Phi*_*ard 20
我会使用Guava的ThreadFactoryBuilder类.
ExecutorService threadPool = Executors.newFixedThreadPool(THREADS, new ThreadFactoryBuilder().setDaemon(true).build());
Run Code Online (Sandbox Code Playgroud)
如果您还没有使用Guava,我会选择一个ThreadFactory子类,如Pshemo的答案顶部所述
如果您只想在一个地方使用它,那么您可以内联java.util.concurrent.ThreadFactory
实现,例如,对于您将编写的具有 4 个线程的池(示例显示为假设 Java 1.8 或更高版本的 lambda):
ExecutorService pool = Executors.newFixedThreadPool(4,
(Runnable r) -> {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
);
Run Code Online (Sandbox Code Playgroud)
但是我通常希望我所有的 Thread 工厂都生成守护线程,所以我添加了一个实用程序类,如下所示:
import java.util.concurrent.ThreadFactory;
public class DaemonThreadFactory implements ThreadFactory {
public final static ThreadFactory instance =
new DaemonThreadFactory();
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
Run Code Online (Sandbox Code Playgroud)
这让我可以轻松地传递DaemonThreadFactory.instance
到ExecutorService
,例如
ExecutorService pool = Executors.newFixedThreadPool(
4, DaemonThreadFactory.instance
);
Run Code Online (Sandbox Code Playgroud)
或使用它轻松地从 启动守护进程线程Runnable
,例如
DaemonThreadFactory.instance.newThread(
() -> { doSomething(); }
).start();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32531 次 |
最近记录: |