在Java8中,Executors.newWorkStealingPool()是否也提供任务队列?
是否存在与Java 8的在Java8中,Executors.newWorkStealingPool()是否也提供任务队列?,java,multithreading,java-8,executorservice,work-stealing,Java,Multithreading,Java 8,Executorservice,Work Stealing,是否存在与Java 8的执行器一起使用的挂起任务队列。newWorkStealingPool() 例如,假设#available cores为2,而Executors.newWorkStealingPool()为空,因为已有2个任务正在运行。那么,如果第三个任务提交给工作执行者,会发生什么情况?它排队了吗?如果是,那么所述队列上的界限是什么 提前谢谢 是否存在与Java 8的Executors.newWorkStealingPool()一起使用的挂起任务队列 是的,每个线程都有自己的deque支
执行器一起使用的挂起任务队列。newWorkStealingPool()
例如,假设#available cores为2,而Executors.newWorkStealingPool()
为空,因为已有2个任务正在运行。那么,如果第三个任务提交给工作执行者,会发生什么情况?它排队了吗?如果是,那么所述队列上的界限是什么
提前谢谢
是否存在与Java 8的Executors.newWorkStealingPool()一起使用的挂起任务队列
是的,每个线程都有自己的deque支持。
当一个线程完成它的任务时,它从另一个线程的任务中获取任务并执行它
如果是,那么所述队列上的界限是什么
队列的最大大小受以下数量限制:static final int Maximum_QUEUE_CAPACITY=1From grepcode of and
Executors
newworksteachingpool
返回ForkJoinPool
执行人:
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
UncaughtExceptionHandler handler,
boolean asyncMode) {
this(checkParallelism(parallelism),
checkFactory(factory),
handler,
asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
"ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
}
ForkJoinPool:
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
UncaughtExceptionHandler handler,
boolean asyncMode) {
this(checkParallelism(parallelism),
checkFactory(factory),
handler,
asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
"ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
}
在execute()
上:
您可以在WorkQueue
类中找到有关队列大小的更多详细信息
static final class WorkQueue {
关于WokrQueue
的文档:
/**
* Queues supporting work-stealing as well as external task
* submission. See above for descriptions and algorithms.
* Performance on most platforms is very sensitive to placement of
* instances of both WorkQueues and their arrays -- we absolutely
* do not want multiple WorkQueue instances or multiple queue
* arrays sharing cache lines. The @Contended annotation alerts
* JVMs to try to keep instances apart.
*/
@sun.misc.Contended
/**
* Capacity of work-stealing queue array upon initialization.
* Must be a power of two; at least 4, but should be larger to
* reduce or eliminate cacheline sharing among queues.
* Currently, it is much larger, as a partial workaround for
* the fact that JVMs often place arrays in locations that
* share GC bookkeeping (especially cardmarks) such that
* per-write accesses encounter serious memory contention.
*/
static final int INITIAL_QUEUE_CAPACITY = 1 << 13;
/**
* Maximum size for queue arrays. Must be a power of two less
* than or equal to 1 << (31 - width of array entry) to ensure
* lack of wraparound of index calculations, but defined to a
* value a bit less than this to help users trap runaway
* programs before saturating systems.
*/
static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M
/**
*支持工作窃取和外部任务的队列
*提交。有关说明和算法,请参见上文。
*在大多数平台上,性能对布局非常敏感
*工作队列及其数组的实例--我们绝对
*不需要多个工作队列实例或多个队列
*共享缓存线的阵列。@contemped注释警报
*JVM尝试将实例分开。
*/
@太阳杂项
/**
*初始化时工作队列数组的容量。
*必须是二的幂;至少4个,但应大于
*减少或消除队列之间的缓存线共享。
*目前,它的规模要大得多,作为
*JVM经常将数组放置在
*共享GC簿记(尤其是卡片标记),以便
*每次写入访问都会遇到严重的内存争用。
*/
静态final int INITIAL_QUEUE_CAPACITY=1我没有一个具体的答案,我很惊讶这没有更好的文档记录。但至少在OpenJDK 8中,这种方法会产生一个阻塞队列,而不是像其他实现那样简单地使用阻塞队列
,这会导致大量争用,导致开销。但是,无法立即执行的任务仍在排队。另一个答案中讨论了这一点(以及队列边界):