我想为工作窃取池使用的 ForkJoinPool 线程设置名称,由
提供ExecutorService newWorkStealingPool(int parallelism)
或
ExecutorService newWorkStealingPool()
到目前为止,我找不到一种方法来在此使用的线程上设置自定义名称
ExecutorService
,有办法吗?
newWorkStealingPool()
基本上提供了 ForkJoinPool
,但是 ForkJoinPool
也没有提供名称模式的公共构造函数。
ForkJoinPool
需要一个线程工厂ForkJoinPool.ForkJoinWorkerThreadFactory
。但工厂应该返回一个 ForkJoinWorkerThread
,它没有公共构造函数。所以我想我必须子类化ForkJoinWorkerThread
。
这似乎是所需的最低代码,重用现有的默认工厂:
final ForkJoinWorkerThreadFactory factory = new ForkJoinWorkerThreadFactory() {
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
worker.setName("my-thread-prefix-name-" + worker.getPoolIndex());
return worker;
}
};
final ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false);
更新 JDK 版本:
final AtomicInteger index = new AtomicInteger();
final ForkJoinPool.ForkJoinWorkerThreadFactory factory = pool -> {
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
worker.setName("my-thread-prefix-name-" + index.getAndIncrement());
return worker;
};
final ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false);
(回复您的更新)
以下内容应该允许您完全控制
ForkJoinPool
生成的线程。就我而言,我希望能够执行“危险”的操作,例如访问系统属性。默认实现使用 java.util.concurrent.ForkJoinWorkerThread.InnocuousForkJoinWorkerThread
,它具有安全管理器和零权限。
public class MyForkJoinThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new NotSoInnocuousWorkerThread(pool);
}
}
和工作线程(现在具有与应用程序的其余部分相同的权限,就像这样,加上您想要的任何其他内容......
public class NotSoInnocuousWorkerThread extends ForkJoinWorkerThread {
protected NotSoInnocuousWorkerThread(ForkJoinPool pool) {
super(pool);
}
}
您需要传递以下属性或在代码中设置它,如下所示:
System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory",
MyForkJoinThreadFactory.class.getName());
这是@Morten Haraldsen 移植到 Kotlin 的答案:
val forkJoinPool =
ForkJoinPool.ForkJoinWorkerThreadFactory { pool ->
ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool).apply {
name = "my-thread-prefix-name-$poolIndex"
}
}.let { factory -> ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, true) }