线程笔记

时间:2020-07-11
本文章向大家介绍线程笔记,主要包括线程笔记使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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);来创建线程池,这样可以根据硬件的不同来设置相对应的参数。

原文地址:https://www.cnblogs.com/zhlblogs/p/13284392.html