是否无法向 ForkJoinPool 提供线程工厂或名称模式?

问题描述 投票:0回答:3

我想为工作窃取池使用的 ForkJoinPool 线程设置名称,由

提供
ExecutorService newWorkStealingPool(int parallelism)

ExecutorService newWorkStealingPool()

到目前为止,我找不到一种方法来在此使用的线程上设置自定义名称

ExecutorService
,有办法吗?

newWorkStealingPool()
基本上提供了
ForkJoinPool
,但是
ForkJoinPool
也没有提供名称模式的公共构造函数。

更新: 我现在找到了这个构造函数

ForkJoinPool
需要一个线程工厂
ForkJoinPool.ForkJoinWorkerThreadFactory
。但工厂应该返回一个
ForkJoinWorkerThread
,它没有公共构造函数。所以我想我必须子类化
ForkJoinWorkerThread

java java.util.concurrent
3个回答
45
投票

这似乎是所需的最低代码,重用现有的默认工厂:

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);

5
投票

(回复您的更新)

以下内容应该允许您完全控制

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());

3
投票

这是@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) }

© www.soinside.com 2019 - 2024. All rights reserved.