前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Executors几种常用的线程池性能比较

Executors几种常用的线程池性能比较

作者头像
菩提树下的杨过
发布2019-06-24 10:35:55
7210
发布2019-06-24 10:35:55
举报

java编程中,经常会利用Executors的newXXXThreasPool生成各种线程池,今天写了一小段代码,简单测试了下三种常用的线程池:

代码语言:javascript
复制
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 测试类(因为要用到forkjoin框架,所以得继承自RecursiveXXX)
 */
public class MathTest extends RecursiveAction {

    private List<Integer> target;

    private static AtomicInteger count = new AtomicInteger(0);

    public MathTest(List<Integer> list) {
        this.target = list;
    }


    public double process(Integer d) {
        //模拟处理数据耗时200ms
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //System.out.println("thread:" + Thread.currentThread().getId() + "-" + Thread.currentThread().getName() + ", d: " + d);
        return d;
    }


    @Override
    protected void compute() {
        if (target.size() <= 2) {
            for (Integer d : target) {
                process(d);
                count.incrementAndGet();
            }
            return;
        }
        int mid = target.size() / 2;
        MathTest t1 = new MathTest(target.subList(0, mid));
        MathTest t2 = new MathTest(target.subList(mid, target.size()));
        t1.fork();
        t2.fork();
    }


    public static void main(String[] args) {
        int num = 100;
        int threadCount = 4;
        List<Integer> target = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            target.add(i);
        }

        MathTest test = new MathTest(target);

        //原始方法,单线程跑
        long start = System.currentTimeMillis();
        for (int i = 0; i < target.size(); i++) {
            test.process(target.get(i));
        }
        long end = System.currentTimeMillis();
        System.out.println("原始方法耗时:" + (end - start) + "\n");


        //固定线程池
        final ThreadFactory fixedFactory = new ThreadFactoryBuilder().setNameFormat("fixed-%d").build();
        ExecutorService service = Executors.newFixedThreadPool(threadCount, fixedFactory);

        count.set(0);
        start = System.currentTimeMillis();
        for (Integer d : target) {
            service.submit(() -> {
                test.process(d);
                count.incrementAndGet();
            });
        }
        while (true) {
            if (count.get() >= target.size()) {
                end = System.currentTimeMillis();
                System.out.println("fixedThreadPool耗时:" + (end - start) + "\n");
                break;
            }
        }


        //cached线程池
        final ThreadFactory cachedFactory = new ThreadFactoryBuilder().setNameFormat("cached-%d").build();
        service = Executors.newCachedThreadPool(cachedFactory);
        count.set(0);
        start = System.currentTimeMillis();
        for (Integer d : target) {
            service.submit(() -> {
                test.process(d);
                count.incrementAndGet();
            });
        }
        while (true) {
            if (count.get() >= target.size()) {
                end = System.currentTimeMillis();
                System.out.println("cachedThreadPool耗时:" + (end - start) + "\n");
                break;
            }
        }


        //newWorkStealing线程池
        service = Executors.newWorkStealingPool(threadCount);
        count.set(0);
        start = System.currentTimeMillis();
        for (Integer d : target) {
            service.submit(() -> {
                test.process(d);
                count.incrementAndGet();
            });
        }
        while (true) {
            if (count.get() >= target.size()) {
                end = System.currentTimeMillis();
                System.out.println("workStealingPool耗时:" + (end - start) + "\n");
                break;
            }
        }


        //forkJoinPool
        ForkJoinPool forkJoinPool = new ForkJoinPool(threadCount);
        count.set(0);
        start = System.currentTimeMillis();
        forkJoinPool.submit(test);
        while (true) {
            if (count.get() >= target.size()) {
                end = System.currentTimeMillis();
                System.out.println("forkJoinPool耗时:" + (end - start) + "\n");
                break;
            }
        }


    }
}

代码很简单,就是给一个List,然后对里面的每个元素做处理(process方法),用三种线程池分别跑了一下,最后看耗时,输出如下:

代码语言:javascript
复制
原始方法耗时:20156

fixedThreadPool耗时:5145

cachedThreadPool耗时:228

workStealingPool耗时:5047

forkJoinPool耗时:5042

环境:mac + intel i5(虚拟4核)。 workStealingPool内部其实就是ForkJoin框架,所以二者在耗时上基本一样,符合预期;如果业务的处理时间较短,从测试结果来看,cachedThreadPool最快。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档