叉不會(一定)創建新的線程。在我的基準測試中,它僅爲每個可用內核+ 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