叉不会(一定)创建新的线程。在我的基准测试中,它仅为每个可用内核+ 1个额外线程创建1个线程。附加基准;说,从main()调用Factorizer.factorize(71236789143834319L)
。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class Factorizer extends RecursiveTask<Long> {
static ForkJoinPool fjPool = new ForkJoinPool();
static final int sequentialThreshold = 10000;
private long number, low, high;
Factorizer(long number, long low, long high) {
this.number = number; this.low = low; this.high = high;
}
private long factorize() {
if ((number % 2) == 0) {
return 2;
}
// ensures i is odd (we already know number is not even)
long i = ((low % 2) == 0) ? low + 1: low;
for (/**/; i < high; i+=2) {
if ((number % i) == 0) {
return i;
}
}
return number;
}
@Override
protected Long compute() {
// ugly debug statement counts active threads
System.err.println(Thread.enumerate(
new Thread[Thread.activeCount()*2]));
if (high - low <= sequentialThreshold) {
return factorize();
} else {
long mid = low + (high - low)/2;
Factorizer left = new Factorizer(number, low, mid);
Factorizer right = new Factorizer(number, mid, high);
left.fork();
return Math.min(right.compute(), left.join());
}
}
static long factorize(long num) {
return fjPool.invoke(new Factorizer(num, 2, (long)Math.sqrt(num+1)));
}
}
注 - 这只是一个测试。不要使用此代码认真地尝试将任何重要因素考虑在内。
我假设Fork-Join的全部重点是从开发者的计算中解放出来,并自动确定给定典型开销和100%并行执行的理想线程数。可能每核心一个。但我不确定。 – tucuxi 2012-07-16 09:19:48
这也是我的想法,但我并不确定,也找不到任何像样的资源可以清除它,并且无法确认我无法使用它。 – 2012-07-16 09:22:33
额外线程的成本非常接近于零,因此不值得担心。这比创建少量线程的惩罚要低很多,创建一些额外的线程是很常见的。你不应该假设开发你的平台的人是傻瓜,你应该使用他们提供给你的工具来达到他们想要的目的。如果他们是白痴,无论如何你都会被搞砸。 – 2012-07-16 09:29:17