美文网首页
Java线程池

Java线程池

作者: longLiveData | 来源:发表于2020-05-23 09:57 被阅读0次

    1.什么是线程池

    java.util.concurrent.Executors 类中提供了很多方法来创建线程池。

    在代码的开头的注释上就写明了,它可以创建重复使用固定数量线程的线程池,如果在所有线程都处于活动状态时提交了其他任务,那么他们将在队列中等待线程可用。

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

    而创建线程池就是为了解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

    做Java的,当然知道线程池,我们在做开发的时候有时候需要做的任务慢慢的增多,复杂性也会变得越来越强,所以线程的个数就会一点点的往上增加,而对应的线程占用的资源也就越来越多,多个线程占用资源的释放与注销需要维护,这时候多个线程的管理就显得有尤为重要。针对这一情况,sun公司提供了线程池,对线程集合的管理工具,所以线程池就出现了。

    2.常见的线程池都有哪些,使用的场景是哪里呢?

    这时候这个java.util.concurrent.Executors 类就排上用场了,比如:

    (1) newSingleThreadExecutor

    // 单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务
    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 threadFactory, defaultHandler);
        }
    

    (2) newFixedThreadPool

    下面的两个方法是这个方法的重载,而它的意思很明确,建立一个线程数量固定的线程池,规定的最大线程数量,超过这个数量之后进来的任务,会放到等待队列中,如果有空闲线程,则在等待队列中获取,遵循先进先出原则。

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

    (3) newCacheThreadExecutor

    缓存型线程池,这个线程池的意思是在核心线程达到最大值之前,如果继续有任务进来就会创建新的核心线程,并加入核心线程池,即使有空闲的线程,也不会复用。

    而达到最大核心线程数后,新任务进来,如果有空闲线程,则直接拿来使用,如果没有空闲线程,则新建临时线程.

    而缓存型的线程池使用的是SynchronousQueue作为等待队列,他不保存任何的任务,新的任务加入进来之后,他会创建临时线程来进行使用

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

    (4) newScheduledThreadPool

    计划型线程池,在它的注释中给出的很明确的解释,创建一个线程池,该线程池可以计划在给定的延迟,或周期性地执行。

    也就是说,在新任务到达的时候,我们看到底有没有空闲线程,如果有,直接拿来使用,如果没有,则新建线程加入池。而这里面使用的就是DelayedWorkQueue作为等待队列,中间进行了一定的等待,等待时间过后,继续执行任务。

        public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
                return new ScheduledThreadPoolExecutor(corePoolSize);
        }
        
        public static ScheduledExecutorService newScheduledThreadPool(
                    int corePoolSize, ThreadFactory threadFactory) {
                return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
         }
    

    3. 阿里巴巴Java开发手册对线程是怎么说的?

    我们在日常使用都是会出现这段代码:

    ExecutorService cachedThreadPool=Executors.newFixedThreadPool();
    

    阿里巴巴Java开发手册中,强制线程池不允许使用 Executors 去创建

    推荐使用 ThreadPoolExecutor

    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }
    

    这个方法里面有几个参数

    • corePoolSize 要保留在池中的线程数,也就是线程池核心池的大小
    • maximumPoolSize 最大线程数
    • keepAliveTime 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
    • unit keepAliveTime 参数的时间单位
    • workQueue 用来储存等待执行任务的队列。
    • threadFactory 线程工厂
    • handler 默认的拒绝执行处理程序

    相关文章

      网友评论

          本文标题:Java线程池

          本文链接:https://www.haomeiwen.com/subject/onfkahtx.html