流管道可以顺序执行或并行执行.此执行模式是流的属性.通过初始选择的顺序或并行执行来创建流.
我的假设:
假设这些假设是有效的(对于一些元假设没有错误),在api中暴露执行模式的价值是什么?
看起来您应该只能声明一个Stream,并且顺序/并行执行的选择应该在下面的层中自动处理,可以通过库代码或JVM本身作为运行时可用核心的函数来处理,大小问题等
当然,假设并行流也可以在单个核心机器上运行,也许只是总是使用并行流来实现这一点.但这真的很难看 - 为什么我的代码中的并行流显式引用它是默认选项?
即使存在您故意想要对顺序流进行硬编码的情况 - 为什么不仅仅是SequentialStream为此目的的子接口,而不是Stream使用执行模式切换进行污染?
我正在比较测试程序的两个变体.两者都ForkJoinPool在具有四个内核的机器上使用4线程运行.
在'模式1'中,我非常像执行器服务使用池.我把一堆任务扔进去ExecutorService.invokeAll.我获得了比普通的固定线程执行器服务更好的性能(即使有调用Lucene,那里也有一些I/O).
这里没有分而治之的.从字面上看,我做到了
ExecutorService es = new ForkJoinPool(4);
es.invokeAll(collection_of_Callables);
Run Code Online (Sandbox Code Playgroud)
在'模式2'中,我向池中提交单个任务,并在该任务中调用ForkJoinTask.invokeAll来提交子任务.所以,我有一个继承自的对象,RecursiveAction它被提交到池中.在该类的compute方法中,我调用了invokeAll来自不同类的对象集合,这些对象也继承自RecursiveAction.出于测试目的,我只提交第一个对象的一次一个.我天真地期望看到所有四个线程忙什么,因为线程调用invokeAll将为自己抓取一个子任务而不是仅仅坐着和阻塞.我可以想到为什么它可能不会那样工作的一些原因.
在VisualVM中观察,在模式2中,一个线程几乎总是在等待.我希望看到的是调用invokeAll的线程立即开始处理其中一个被调用的任务,而不仅仅是静坐.这肯定比使用普通线程池尝试此方案所导致的死锁更好,但仍然是什么?它是否保留一个线程,以防其他东西被提交?而且,如果是这样,为什么模式1中的问题不同?
到目前为止,我一直使用添加到java 1.6的引导类路径的jsr166 jar来运行它.
我尝试使用ForkJoinPool 来并行化我的CPU密集型计算.我对ForkJoinPool的理解是,只要任何任务可以执行,它就会继续工作.不幸的是,我经常观察工作线程空闲/等待,因此并非所有CPU都保持忙碌状态.有时我甚至观察到额外的工作线程.
我没想到这一点,因为我严格尝试使用非阻塞任务.我的观察非常类似于ForkJoinPool似乎浪费了一个线程.在对ForkJoinPool进行了大量调试之后我猜了一下:
我使用invokeAll()在子任务列表上分配工作.在invokeAll()完成后执行第一个任务本身,它开始加入其他任务.这很好,直到下一个要连接的任务位于执行队列之上.不幸的是,我提交了异步的其他任务而没有加入它们.我期望ForkJoin框架首先继续执行这些任务,然后再转回加入任何剩余的任务.
但它似乎不是这样工作的.相反,工作线程停止调用wait()直到等待的任务准备好(可能是由其他工作线程执行).我没有验证这一点,但似乎是调用join()的一般缺陷.
ForkJoinPool提供了一个asyncMode,但这是一个全局参数,不能用于单个提交.但我喜欢看到我的异步分叉任务很快就会被执行.
那么,为什么ForkJoinTask.doJoin()不是简单地在其队列之上执行任何可用任务,直到它准备好(由自己执行或被其他人窃取)?
是否可以配置ForkJoinPool为使用1个执行线程?
我正在执行Random在一个内部调用的代码ForkJoinPool.每次运行时,我都会遇到不同的运行时行为,因此很难调查回归.
我希望代码库提供"调试"和"发布"模式."debug"模式将Random使用固定种子配置,并ForkJoinPool使用单个执行线程."release"模式将使用系统提供的Random种子并使用默认的ForkJoinPool线程数.
我尝试ForkJoinPool使用1的并行性配置,但它使用2个线程(main和第二个工作线程).有任何想法吗?
我有一个关于使用fork join线程池的简单问题.这是我正在使用的一个简短示例:
executor = "fork-join-executor"
# Configuration for the fork join pool
fork-join-executor {
# Min number of threads to cap factor-based parallelism number to
parallelism-min = 24
# Parallelism (threads) ... ceil(available processors * factor)
parallelism-factor = 4.0
# Max number of threads to cap factor-based parallelism number to
parallelism-max = 48
}
Run Code Online (Sandbox Code Playgroud)
我不确定的是,在这种情况下会创建多少个线程?我正在运行2核心机器,因此每个核心有24个线程,最多48个线程?
并行因子设置为4.0时,可并行运行的线程数将为8.那么设置最小值和最大值的需要是什么,我的情况是24和48?
fork-join ×4
java ×4
akka ×1
forkjoinpool ×1
java-7 ×1
java-8 ×1
java-stream ×1
lock-free ×1
scala ×1