zoukankan      html  css  js  c++  java
  • 线程池的创建方法推荐

    使用Executors创建线程池的四种方法:


    Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。

    1.public static ExecutorService newFixedThreadPool(int nThreads)

                创建固定数目线程的线程池。

    2.public static ExecutorService newCachedThreadPool()

                创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

    3.public static ExecutorService newSingleThreadExecutor()

                创建一个单线程化的Executor。

    4.public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

                创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

    ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

    以上四种创建线程池实则并不推荐,并避免使用。

    推荐:使用ThreadPoolExecutor的方式创建线程池


    线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险

    说明:Executors返回的线程池对象的弊端如下:

    1)FixedThreadPool和SingleThreadPool:

      允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。

    2)CachedThreadPool:

      允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

                

    Positive example 1:

        //org.apache.commons.lang3.concurrent.BasicThreadFactory
    
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
    
            new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());

                

    Positive example 2:

        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() .setNameFormat("demo-pool-%d").build();
    
        //Common Thread Pool
    
        ExecutorService pool = new ThreadPoolExecutor(5, 200,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    
        pool.execute(()-> System.out.println(Thread.currentThread().getName()));
    
        pool.shutdown();//gracefully shutdown

    Positive example 3:

        <bean id="userThreadPool"
    
            class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    
            <property name="corePoolSize" value="10" />
    
            <property name="maxPoolSize" value="100" />
    
            <property name="queueCapacity" value="2000" />
    
    
    
        <property name="threadFactory" value= threadFactory />
    
            <property name="rejectedExecutionHandler">
    
                <ref local="rejectedExecutionHandler" />
    
            </property>
    
        </bean>
    
        //in code
    
        userThreadPool.execute(thread);

    以上为阿里巴巴推荐的方式。

    结合阿里巴巴代码规范的推荐方式,以下为我公司现使用的方式:

    // 成员变量
    private volatile ExecutorService executor;
    
    //单例模式创建
    private ExecutorService getExecutorService(){
            if(executor == null){
                synchronized (this){
                    if(executor == null){
                        int availableProcessors = Runtime.getRuntime().availableProcessors();
                        int maximumPoolSize = availableProcessors * 4;
                        int queueCapacity = availableProcessors * 100;
                        long keepAliveTime = 60L;
                        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(queueCapacity);
                        executor = new ThreadPoolExecutor(
                                availableProcessors,
                                maximumPoolSize,
                                keepAliveTime,
                                TimeUnit.SECONDS,
                                workQueue,
                                new ThreadPoolExecutor.DiscardPolicy());
    
                        // 关闭客户端(关闭后台线程)
                        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                            if(Objects.nonNull(executor)){
                                executor.shutdown();
                            }
                        }));
                    }
                }
            }
            return executor;
        }

       

  • 相关阅读:
    What is Split Brain in Oracle Clusterware and Real Application Cluster (文档 ID 1425586.1)
    Oracle Grid Infrastructure: Understanding Split-Brain Node Eviction (文档 ID 1546004.1)
    代理模式和装饰者模式区别
    偏向锁、轻量级锁、重量级锁
    理解HTTP幂等性
    Java8 lambda表达式10个示例
    IDEA debug断点调试技巧
    【1】【leetcode-115 动态规划】 不同的子序列
    【leetcode-91 动态规划】 解码方法
    【leetcode-78 dfs+回溯】 子集
  • 原文地址:https://www.cnblogs.com/qukun/p/12314936.html
Copyright © 2011-2022 走看看