只要我在池中给ForkJoinPool 一个额外的线程,它的执行速度就和ExecutorService一样快。下面是使用的三个类: Main、RunnableTask和ForkJoinTask。运行在16核盒上的程序每次输出如下:执行器时间: 5002 ForkJoin时间: 5002
主要班:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
public class Main {
public static void main(String[] args) throws InterruptedException {
runExecutor(80);
runForkJoin(80);
}
public static void runForkJoin(int size) {
ForkJoinPool fjp = new ForkJoinPool(17);
long start = System.currentTimeMillis();
fjp.invoke(new ForkJoinTask(size));
System.out.println("ForkJoin Time: "
+ (System.currentTimeMillis() - start));
fjp.shutdown();
}
public static void runExecutor(int size) throws InterruptedException {
ExecutorService exec = Executors.newFixedThreadPool(16);
CountDownLatch latch = new CountDownLatch(size);
long start = System.currentTimeMillis();
for (int i = 0; i < latch.getCount(); i++) {
exec.submit(new RunnableTask(latch));
}
latch.await();
System.out.println("Executor Time: "
+ (System.currentTimeMillis() - start));
exec.shutdown();
}
}可运行的课程:
import java.util.concurrent.CountDownLatch;
public class RunnableTask implements Runnable {
private CountDownLatch latch;
public RunnableTask(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
} catch (Exception e) {
}
}
}RecursiveTask类:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;
public class ForkJoinTask extends RecursiveTask {
private List<RecursiveTask> tasks;
private int size;
public ForkJoinTask(int size) {
super();
this.tasks = new ArrayList<>();
this.size = size;
}
@Override
protected Object compute() {
for (int i = 0; i < size; i++) {
RecursiveTask task = new RecursiveTask() {
@Override
protected Object compute() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
return null;
}
};
task.fork();
tasks.add(task);
}
for (RecursiveTask task : tasks) {
task.join();
}
return null;
}
}发布于 2013-03-27 19:32:07
您的单个任务可以使( ForkJoinPool和ExecutorService )比现在运行得更快,而且这两个任务都不应该比另一个具有实质性的优势。
原因是如果单个计算任务是Thread.sleep(1000),那么任务不需要CPU资源。您可以增加线程数量以匹配作业大小( 80 ),并在超过1秒的时间内完成80秒的“work”,因为线程实际上不会竞争任何类型的资源。
至于ForkJoinPool和ExecutorService之间的比较,这种差异与您的测试用例无关,因为您的工作不产生任何应该作为进一步计算的输入的内容(MapReduce中的“减少”步骤)。因此,对您来说,它们都只是具有不同API的线程池。
https://stackoverflow.com/questions/15666978
复制相似问题