代码改变世界
[登录 · 注册]
  • Executors几种常用的线程池性能比较
  • java编程中,经常会利用Executors的newXXXThreadsPool生成各种线程池,今天写了一小段代码,简单测试了下三种常用的线程池:

    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) + "
    ");
    
    
            //固定线程池
            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) + "
    ");
                    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) + "
    ");
                    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) + "
    ");
                    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) + "
    ");
                    break;
                }
            }
    
    
        }
    }
    

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

    原始方法耗时:20156
    
    fixedThreadPool耗时:5145
    
    cachedThreadPool耗时:228
    
    workStealingPool耗时:5047
    
    forkJoinPool耗时:5042

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

  • 上一篇:pulsar学习笔记1:helloworld
    下一篇:mac上利用minikube搭建kubernetes(k8s)环境
  • 【推广】 阿里云小站-上云优惠聚集地(新老客户同享)更有每天限时秒杀!
    【推广】 云服务器低至0.95折 1核2G ECS云服务器8.1元/月
    【推广】 阿里云老用户升级四重礼遇享6.5折限时折扣!
  • 原文:https://www.cnblogs.com/yjmyzz/p/11073433.html
走看看 - 开发者的网上家园