我一直在研究JDK 7中的新功能,即Fork和Join。在Javadoc中,它声明在ForkJoinTask
中只能在ForkJoinPool
的上下文中执行fork。但它没有提到fork()
方法调用是否创建了新线程。
ForkJoinPool
使用工作窃取算法来平衡线程之间的工作,但没有提到实际创建了多少线程。
我有一个任务,我应该以分而治的方式分解,但我担心ForkJoinPool
会创建太多线程,并且会因为管理这些线程的开销而降低执行性能
有人可以帮我吗?
答案 0 :(得分:0)
Fork不(必然)创建新线程。在我的基准测试中,它只为每个可用核心创建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)));
}
}
注意 - 这只是一个测试。不要使用此代码来认真考虑任何重要因素。