如果我想在后台任务中并行运行一个流,是否可以以较低的优先级运行它? 如果可以,如何做到?
如果我想在后台任务中并行运行一个流,是否可以以较低的优先级运行它? 如果可以,如何做到?
是的,这是可能的。
步骤如下:
创建一个ForkJoinWorkerThreadFactory
,使用适当的优先级创建线程。
使用上述线程工厂创建一个ForkJoinPool
。
实例化并行流。
通过将其提交到ForkJoinPool
来运行流。
类似于这样:
public class MyThread extends ForkJoinWorkerThread {
public MyThread(ForkJoinPool pool, int priority) {
super(pool);
setPriority(priority);
}
}
final int poolSize = ...
final int priority = ...
List<Long> aList = LongStream.rangeClosed(firstNum, lastNum).boxed()
.collect(Collectors.toList());
ForkJoinWorkerThreadFactory factory = new ForkJoinWorkerThreadFactory() {
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new MyThread(pool, priority);
}
};
/*
ForkJoinWorkerThreadFactory factory = pool -> new MyThread(
pool,
priority
);
*/
ForkJoinPool customThreadPool = new ForkJoinPool(
poolSize, factory, null, false);
long actualTotal = customThreadPool.submit(
() -> aList.parallelStream().reduce(0L, Long::sum)).get();
(示例代码改编自http://www.baeldung.com/java-8-parallel-streams-custom-threadpool)
我可以翻译这段文本。我认为更好的方法是像这里描述的那样:
public class CustomForkJoinWorkerThreadFactory implements ForkJoinWorkerThreadFactory {
private final int threadPriority;
public CustomForkJoinWorkerThreadFactory(int threadPriority) {
this.threadPriority = threadPriority;
}
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool)
{
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
worker.setPriority(threadPriority);
return worker;
}
}
new ForkJoinPool(poolSize, new CustomForkJoinWorkerThreadFactory(Thread.MIN_PRIORITY), null, false);
前一个答案的内联版本
new ForkJoinPool(parallelism, (pool) -> {
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setPriority(NORM_PRIORITY + 1);
return thread;
}, null, false);
ForkJoinWorkerThreadFactory factory = pool -> new ForkJoinWorkerThread(pool) {{ setPriority(priority); }};
- shmoselsubmit
会抛出InterruptedException
,需要进行处理。 - Stephen CForkJoinPool.ForkJoinWorkerThreadFactory
是一个(结构上的)函数式接口,因此工厂可以定义为pool -> new MyThread(pool, priority)
。 - srborlongan