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;
        }

       

  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/qukun/p/12314936.html
Copyright © 2011-2022 走看看