zoukankan      html  css  js  c++  java
  • Java 线程池手动配置ThreadPoolExecutor

    线程池中,常见有涉及到的:

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    ExecutorService executorService1 = Executors.newCachedThreadPool();
    ExecutorService executorService2 = Executors.newFixedThreadPool(3);

    关于Executors和ExecutorService记忆上类似于Collections和List。

    但是以上几种其实不建议使用。最好可以通过自己手动配置ThreadPoolExecutor的形式。

    我先创建一个demo:

    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                    2,
                    5,
                    1L,
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<Runnable>(3),
                    Executors.defaultThreadFactory(),
                    new ThreadPoolExecutor.AbortPolicy()
            );

    涉及7个参数,按顺序分别是

    int corePoolSize, 
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler

    具体我首先需要结合参数解释下线程池的执行原理:

    画了张图:

     如果我用银行办理业务示例说明如下:

    1、首先银行里面有两个柜台,这就是核心线程数(7大参数之一)。

    2、然后随着客户的增加,可能这个两个柜台满了,然后就要请用户到等候区里面进行等待。这个等候区就是相当于阻塞队列(七大参数之一)。

    3、然后紧接着客户越来越多,连阻塞队列都撑不住了,这个时候,就要请求,上面的领导进行多增加柜台的操作,这个时候,可能加了三个柜台,现在就有5个柜台了。这个时候最大的线程数(七大参数之一)就是5了。

    4、但是这个时候可能客户又越来越多,这个时候新加的柜台也受不了,就要开始有拒绝策略了(七大参数之一)

    5、然后过了一段时间,慢慢的,客户越来越少了,这个时候,发现渐渐的,柜台空余出来了。KeepAliveTime(七大参数之一,加上单位,合计两个参数)指当线程数大于核心线程数时,此为终止前多余的空闲线程等待新任务的最长时间。

    6、还有一个参数是工厂,这个我们不做深入研究,直接用默认的工厂即可。

    懂得原理以后,我们可以查看下,为什么最好不要直接用,比如:

    Executors.newFixedThreadPool(3);

    这个的主要原因就是这里面默认队列的最大值是Integer的最大值。

     

    所以我们生产中需要自己配置线程池。因为默认队列的长度太长了,有可能会导致oom。就是内存炸掉了。

     这个在阿里的编程思想里面也有说明这一点:

    这边我们探讨下,拒绝策略。4种策略。就是所有柜台和等候区全部满了。会如何处理。

    用非常easy的代码来过下,这块的内容:

    1、AbortPolicy

    import java.util.concurrent.*;
    
    public class VolatileTest {
        public static void main(String[] args) throws Exception {
            ExecutorService executorService = new ThreadPoolExecutor(
                    2,
                    5,
                    1L,
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<Runnable>(3),
                    Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()
            );
    
            try {
                for (int i = 0; i < 9; i++) {
                    executorService.execute(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(Thread.currentThread().getName()+"	"+"办理业务");
                        }
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
    
        }
    }

     

     可以看到如果超出的话直接挂了,阻止正常运行。

    2、CallerRunsPolicy

    输出

     发现有一个退回main线程,被main线程处理。即会把任务退回至调用者。

    3、DiscardOldestPolicy

    这个将会等待时间最久的任务丢掉。

    4、DiscardPolicy

    多出来的任务会全部丢掉。

     

     

  • 相关阅读:
    蜘蛛修网
    推荐10款用户界面设计
    18个web开发人员必备的Chrome扩展
    分享一个帮助你在线测试响应式设计的web工具 Screenqueri.es
    推荐16款每周设计灵感
    分享一个帮助你快速构建HTML5游戏的javascript类库 CreateJS
    5个jQuery的备选轻量级移动客户端开发(Mobile development)类库
    帮助你高效开发Ajax应用的超酷jQuery插件 AjaxML
    免费资源:350个超棒标志性字符图标
    免费素材下载:超酷的简单按钮UI
  • 原文地址:https://www.cnblogs.com/chenmz1995/p/12859981.html
Copyright © 2011-2022 走看看