zoukankan      html  css  js  c++  java
  • 线程笔记

    1.使用线程池时,生产环境中线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式的原因:

       使用Executors创建线程池有三种方式:

          1.newCachedThreadPool():创建缓存线程池。

          当一个任务提交时,corePoolSize为0不创建核心线程,SynchronousQueue是一个不存储元素的队列,可以理解为队里永远是满的,因此最终会创建非核心线程来执行任务。

            对于非核心线程空闲60s时将被回收。因为Integer.MAX_VALUE非常大,可以认为是可以无限创建线程的,在资源有限的情况下容易引起OOM异常

          源码为:

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    

          2.newSingleThreadExecutor():创建单线程的线程池。

          当一个任务提交时,首先会创建一个核心线程来执行任务,如果超过核心线程的数量,将会放入队列中,因为LinkedBlockingQueue是长度为Integer.MAX_VALUE的队列,可以认为是无界队列,因此往队列中可以插入无限多的任务,

            在资源有限的时候容易引起OOM异常,同时因为无界队列,maximumPoolSize和keepAliveTime参数将无效,压根就不会创建非核心线程

          源码为:

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

          3.newFixedThreadPool():创建指定线程数的线程池。

          FixedThreadPool是固定核心线程的线程池,固定核心线程数由用户传入,同样是因为LinkedBlockingQueue是长度为Integer.MAX_VALUE的队列,可以认为是无界队列,容易引起OOM异常

          源码为:

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

      以上三种方式都是执行:new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime, TimeUnit.MILLISECONDS,runnableTaskQueue);五个参数分别为:核心线程数,最大线程数,存活前最大空闲时间(针对非核心线程),时间单位,任务队列(等待执行任务的队列)

      

    执行逻辑:

    1.判断核心线程数是否已满,未满则创建线程执行任务
    
    2.若核心线程池已满,判断队列是否满,若未满则加入队列中
    
    3.若队列已满,判断线程池是否已满,若未满创建线程执行任务
    
    4.若线程池已满,则采用拒绝策略处理无法执执行的任务

    因此:建议开发者自己使用new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime, TimeUnit.MILLISECONDS,runnableTaskQueue, threadFactory,handler);来创建线程池,这样可以根据硬件的不同来设置相对应的参数。

    2.DCL(Double check Lock)双检查锁,先检查缓存中对象是否存在,不存在则加锁,然后再判断缓存中对象是否存在,存在则直接返回,不存在则从数据库中查询,然后保存到缓存中

  • 相关阅读:
    两个路由器配置静态路由只能单边 ping 通
    CVE202125646:Apache Druid远程命令执行漏洞复现
    批量修改图片的格式
    十大远程控制软件排名
    Splashtop 免费60天 大赠送
    单例设计模式
    蓄水池抽样算法/水塘采样算法
    kafka安装(单机版)
    LeetCode382链表随机节点
    LeetCode398随机数索引
  • 原文地址:https://www.cnblogs.com/zhlblogs/p/13284392.html
Copyright © 2011-2022 走看看