• java并行之parallelStream与CompletableFuture比较


    1.

    import java.util.Arrays;
    import java.util.List;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toList;
    
    
    public class CompletableFutureTest {
        static final UserFeatureable[] UserFeatures = {new GetCareerUserFeature(), new GetTradeUserFeature(), new
                GetVipLevelUserFeature()};
    
        public static void main(String[] args) {
            int id = 10001;
            List<UserFeatureable> userFeatures = Arrays.asList(UserFeatures);
            long startTime = System.currentTimeMillis();
            String result = userFeatures.parallelStream().map(p -> p.getKey() + ":" + p.getValue(id)).collect(joining(","));
            long endTime = System.currentTimeMillis();
            System.out.println(String.format("parallelStream消耗时间:%d,返回结果:%s", (endTime - startTime), result));
    
            startTime = System.currentTimeMillis();
            List<Future<String>> futureList = userFeatures.stream().map(
                    p -> CompletableFuture.supplyAsync(() -> p.getKey() + ":" + p.getValue(id)))
                    .collect(toList());
            result = futureList.stream().map(p->getVal(p,"")).collect(joining(","));
            endTime = System.currentTimeMillis();
            System.out.println(String.format("CompletableFuture的默认的ForkJoin线程池消耗时间:%d,返回结果:%s", (endTime - startTime),
                    result));
    
            //当userFeature越多,使用自定义线程池更有利
            startTime = System.currentTimeMillis();
            futureList = userFeatures.stream().map(
                    p -> CompletableFuture.supplyAsync(() -> p.getKey() + ":" + p.getValue(id),CustomThreadPool.INSTANCE))
                    .collect(toList());
            result = futureList.stream().map(p->getVal(p,"")).collect(joining(","));
            endTime = System.currentTimeMillis();
            System.out.println(String.format("CompletableFuture的自定义线程池消耗时间:%d,返回结果:%s", (endTime - startTime), result));
        }
    
        private static <T>T getVal(Future<T> future,T defaultV){
            try {
                return future.get(2,TimeUnit.SECONDS);
            }catch (Exception ex){
                return defaultV;
            }
        }
    }
    
    interface UserFeatureable {
        String getKey();
    
        String getValue(int id);
    }
    
    class GetCareerUserFeature implements UserFeatureable {
    
        @Override
        public String getKey() {
            return "career";
        }
    
        @Override
        public String getValue(int id) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
    
            }
            return "10";
        }
    }
    
    class GetTradeUserFeature implements UserFeatureable {
    
        @Override
        public String getKey() {
            return "trade";
        }
    
        @Override
        public String getValue(int id) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
    
            }
            return "5";
        }
    }
    
    class GetVipLevelUserFeature implements UserFeatureable {
    
        @Override
        public String getKey() {
            return "vip";
        }
    
        @Override
        public String getValue(int id) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
    
            }
            return "v1";
        }
    }

    2.自定义线程池配置

    import com.google.common.util.concurrent.ThreadFactoryBuilder;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    
    public class CustomThreadPool {
        /**
         * 默认核心线程池大小
         */
        private static final int DEFAULT_CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    
        /**
         * 最大线程池大小
         * 最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目
         * 最佳线程数目 = (1s/0.1s + 1) * CPU数目
         */
        private static final int DEFAULT_MAXIMUM_POOL_SIZE = 11 * DEFAULT_CORE_POOL_SIZE;
    
        /**
         * 超过核心线程后,空闲线程等待时间
         */
        private static final long DEFAULT_KEEP_ALIVE_SECONDS = 10;
    
        /**
         * 等待执行的线程队列
         */
        private static BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingDeque(DEFAULT_MAXIMUM_POOL_SIZE * 2);
    
        public static ThreadPoolExecutor INSTANCE = new ThreadPoolExecutor(
                DEFAULT_CORE_POOL_SIZE,
                DEFAULT_MAXIMUM_POOL_SIZE,
                DEFAULT_KEEP_ALIVE_SECONDS,
                TimeUnit.SECONDS,
                WORK_QUEUE,
                new ThreadFactoryBuilder().setNameFormat("task-pool-thread-%d").build());
    
    }

    3.结果

    parallelStream消耗时间:2889,返回结果:career:10,trade:5,vip:v1
    CompletableFuture的ForkJoin线程池消耗时间:1010,返回结果:career:10,trade:5,vip:v1
    CompletableFuture的自定义线程池消耗时间:1011,返回结果:career:10,trade:5,vip:v1
  • 相关阅读:
    Spring缓存注解@Cache使用
    Java中BigDecimal的8种舍入模式
    mysql和oracle的mybatis操作
    MyEclipse开发JAX-RS架构WebServices收发JSON数据格式
    Hibernate 常见异常
    SQL笔试题
    Map按键排序(sort by key)
    Spring+Mybatis常见问题随笔
    md5utils
    Http请求中Content-Type讲解以及在Spring MVC中的应用
  • 原文地址:https://www.cnblogs.com/zhshlimi/p/9776477.html
Copyright © 2020-2023  润新知