zoukankan      html  css  js  c++  java
  • 线程池的使用

    1、在阿里巴巴Java开发手册中也明确指出,不允许使用Executors创建线程池。
    阿里巴巴java开发手册说明如下:
    【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

    说明:Executors返回的线程池对象的弊端如下:
    FixedThreadPool和SingleThreadPool:允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
    CachedThreadPool和ScheduledThreadPool:允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM

    2、固定线程池:创建固定数目线程的线程池

        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }

    单例线程池:创建一个单线程化的Executor

        public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
        }

    newFixedThreadPool和newSingleThreadExecutor的阻塞队列均使用的LinkedBlockingQueue,是一个用链表实现的阻塞队列,不设置容量的话,默认最大长度为Integer.MAX_VALUE,这样就不断的向队列中加入任务的,创建的最大线程数可能是Integer.MAX_VALUE,而创建这么多线程,必然就有可能导致OOM。

    3、

    public class ThreadPoolExecutorUtils {
    
        private static int CORE_POOL_SIZE = 10;
        private static int MAX_POOL_SIZE = 20;
        private static long KEEP_ALIVE_TIME = 30;
        private static int QUEUE_SIZE = 200;
        private static String THREAD_POOL_NAME = "thread-pool";
        private static volatile ExecutorService pool = null;
    
        private ThreadPoolExecutorUtils(){
    
        }
        public static ExecutorService getPool() {
            // 使用双重校验锁保证只有一个pool实例
            if (pool == null) {
                synchronized (ThreadPoolExecutorUtils.class) {
                    if (pool == null) {
                        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(THREAD_POOL_NAME + "-%d").build();
                        pool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                                new LinkedBlockingQueue<>(QUEUE_SIZE), namedThreadFactory,
                                new ThreadPoolExecutor.AbortPolicy());
                    }
                }
            }
            return pool;
        }
    }        

    总结引用:https://mp.weixin.qq.com/s/kefLFjLTOZuwmklrMPAOLA

    N核服务器,通过执行业务的单线程分析出本地计算时间为x,等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化。

    一般来说,非CPU密集型的业务(加解密、压缩解压缩、搜索排序等业务是CPU密集型的业务),瓶颈都在后端数据库访问或者RPC调用,本地CPU计算的时间很少,所以设置几十或者几百个工作线程是能够提升吞吐量的。

  • 相关阅读:
    使用注解方式实现 AOP和IoC
    代理工厂生成器和顾问包装通知
    多种方式实现AOP
    Spring面试题
    使用集合方式注入IoC
    Spring代理模式
    Spring AOP的使用及案例
    bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞 -- spfa判断负环
    bzoj 1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会 -- Tarjan
    bzoj 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚 -- 线段树
  • 原文地址:https://www.cnblogs.com/tilamisu007/p/12056294.html
Copyright © 2011-2022 走看看