首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在这种情况下,ForkJoinPool能比ExecutorService更快吗?

在这种情况下,ForkJoinPool能比ExecutorService更快吗?
EN

Stack Overflow用户
提问于 2013-03-27 18:47:11
回答 1查看 1.6K关注 0票数 2

只要我在池中给ForkJoinPool 一个额外的线程,它的执行速度就和ExecutorService一样快。下面是使用的三个类: Main、RunnableTask和ForkJoinTask。运行在16核盒上的程序每次输出如下:执行器时间: 5002 ForkJoin时间: 5002

主要班:

代码语言:javascript
复制
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();
    }
}

可运行的课程:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-27 19:32:07

您的单个任务可以使( ForkJoinPoolExecutorService )比现在运行得更快,而且这两个任务都不应该比另一个具有实质性的优势。

原因是如果单个计算任务是Thread.sleep(1000),那么任务不需要CPU资源。您可以增加线程数量以匹配作业大小( 80 ),并在超过1秒的时间内完成80秒的“work”,因为线程实际上不会竞争任何类型的资源。

至于ForkJoinPoolExecutorService之间的比较,这种差异与您的测试用例无关,因为您的工作不产生任何应该作为进一步计算的输入的内容(MapReduce中的“减少”步骤)。因此,对您来说,它们都只是具有不同API的线程池。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15666978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档