通常当使用Java 8的parallelStream()时,结果是通过默认的公共fork-join池(即ForkJoinPool.commonPool())执行。
然而,如果一个人的工作远离CPU限制,那么这显然是不可取的。可能在很多时候都在等待IO。在这种情况下,人们会想要使用一个单独的池,根据其他标准确定大小(例如,任务可能实际使用CPU的时间有多少)。
没有显而易见的让parallelStream()使用不同的池的方法,但有一种方法详细here。
不幸的是,这种方法需要从fork-join池线程调用并行流上的终端操作。这样做的缺点是,如果目标分支连接池完全忙于现有工作,整个执行将等待它,而什么都不做。因此,池可能成为比单线程执行更糟糕的瓶颈。相比之下,当一个人在" normal"中使用parallelStream()时fashion,ForkJoinPool.common.externalHelpComplete()或ForkJoinPool.common.tryExternalUnpush()用于让来自池外的调用线程帮助处理。
有没有人知道两者的方法让parallelStream()使用非默认的fork-join池和有一个来自fork-join外部的调用线程池帮助处理这项工作(但不是其余的fork-join池'
答案 0 :(得分:2)
您可以在游泳池上使用-s
来提供帮助。但是,您无法选择要提供帮助的任务,它只会从池中获取下一个待处理项,因此,如果有更多待处理任务,您可能最终会在执行这些任务之前执行这些任务。
awaitQuiescence
将打印ForkJoinPool forkJoinPool = new ForkJoinPool(1);
// make all threads busy:
forkJoinPool.submit(() -> LockSupport.parkNanos(Long.MAX_VALUE));
// submit our task (may contain your stream operation)
ForkJoinTask<Thread> task = forkJoinPool.submit(() -> Thread.currentThread());
// help out
while(!task.isDone()) // use zero timeout to execute one task only
forkJoinPool.awaitQuiescence(0, TimeUnit.NANOSECONDS);
System.out.println(Thread.currentThread()==task.get());
。
,而
true
会在尝试执行第二个阻止任务时永远挂起。
然而,只要没有无限的任务,它就会让启动线程帮助处理池的挂起任务,这将增加自己的任务执行的可能性(上面的示例是极端的,只是为了演示而选择)。 / p>
但请注意,Fork / Join框架和ForkJoinPool forkJoinPool = new ForkJoinPool(1);
// make all threads busy:
forkJoinPool.submit(() -> LockSupport.parkNanos(Long.MAX_VALUE));
// overload:
forkJoinPool.submit(() -> LockSupport.parkNanos(Long.MAX_VALUE));
// submit our task (may contain your stream operation)
ForkJoinTask<Thread> task = forkJoinPool.submit(() -> Thread.currentThread());
// help out
while(!task.isDone())
forkJoinPool.awaitQuiescence(0, TimeUnit.NANOSECONDS);
System.out.println(Thread.currentThread()==task.get());
API之间的整个关系无论如何都是一个实现细节。