不能为 ForkJoinPool 提供线程工厂或名称模式吗?
Is it not possible to supply a thread facory or name pattern to ForkJoinPool?
我想为工作窃取池使用的 ForkJoinPool 线程设置名称,由
提供
ExecutorService newWorkStealingPool(int parallelism)
或
ExecutorService newWorkStealingPool()
到目前为止我找不到在这个 ExecutorService
使用的线程上设置自定义名称的方法,有什么办法吗?
newWorkStealingPool()
基本上提供了一个 ForkJoinPool
,但是 ForkJoinPool
也没有一个 public 具有提供的名称模式的构造函数。
更新:
我现在找到了这个构造函数
ForkJoinPool
需要一个线程工厂 ForkJoinPool.ForkJoinWorkerThreadFactory
。但是工厂应该 return 一个 ForkJoinWorkerThread
,它没有 public 构造函数。所以我想我将不得不继承 ForkJoinWorkerThread
.
(回答您的更新)
以下应该允许您完全控制由您的 ForkJoinPool
生成的线程。就我而言,我希望能够执行 "dangerous" 访问系统属性之类的操作。默认实现使用具有安全管理器和零权限的 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());
这似乎是最低要求的代码,重用了现有的默认工厂:
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;
}
};
forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false);
这是移植到 Kotlin 的@Morten Haraldsen 的回答:
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) }
我想为工作窃取池使用的 ForkJoinPool 线程设置名称,由
提供ExecutorService newWorkStealingPool(int parallelism)
或
ExecutorService newWorkStealingPool()
到目前为止我找不到在这个 ExecutorService
使用的线程上设置自定义名称的方法,有什么办法吗?
newWorkStealingPool()
基本上提供了一个 ForkJoinPool
,但是 ForkJoinPool
也没有一个 public 具有提供的名称模式的构造函数。
更新:
我现在找到了这个构造函数
ForkJoinPool
需要一个线程工厂 ForkJoinPool.ForkJoinWorkerThreadFactory
。但是工厂应该 return 一个 ForkJoinWorkerThread
,它没有 public 构造函数。所以我想我将不得不继承 ForkJoinWorkerThread
.
(回答您的更新)
以下应该允许您完全控制由您的 ForkJoinPool
生成的线程。就我而言,我希望能够执行 "dangerous" 访问系统属性之类的操作。默认实现使用具有安全管理器和零权限的 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());
这似乎是最低要求的代码,重用了现有的默认工厂:
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;
}
};
forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false);
这是移植到 Kotlin 的@Morten Haraldsen 的回答:
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) }