zoukankan      html  css  js  c++  java
  • 线程池原理简析

    扫扫盲

    只要是参加过Java培训或Java开发工作的同学,肯定或多或少的都知道线程池。

    线程池的优势就是避免让你无限制的创建很多很多的线程,而且不需要频繁的创建和删除线程。

    那线程池的工作原理到底是什么呢?

    这里举一个简单的例子:

    ExecutorService threedPool = Executors.newFixedThreadPool(3);
    

    这段代码的意思是创建一个只能容纳三个线程的线程池。

    这个3就是corePoolSize。

    corePoolSize 表示常驻核心线程数。如果其等于0,则任务执行完之后,没有任何请求进入时销毁线程池的线程;如果大于0,即使本地任务执行完毕,核心线程也不会被销毁。

    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    
    /**
         * Creates a {@code LinkedBlockingQueue} with a capacity of
         * {@link Integer#MAX_VALUE}.
         */
        public LinkedBlockingQueue() {
            this(Integer.MAX_VALUE);
        }
    
    

    newFixedThreadPool(3)创建了一个常驻核心线程数大小为3、线程池能够容纳的同事执行的最大线程数为3,线程空闲时间为0,单位为毫秒的,缓存队列是无界阻塞队列的线程池。

    Java开发规范中【强制】要求线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

    说明:Executors 返回的线程池对象的弊端如下:

    1) FixedThreadPool 和 SingleThreadPool:

    允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

    2) CachedThreadPool:

    允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

    我们这里使用newFixedThreadPool只是为了举例而已,大家在开发过程中还是建议大家按照开发规范要求来进行处理。

    有一个任务来了

    当线程池中来了第一个任务的时候。假设这个任务是这样的。

    threadPool.execute(new Runnable() {
                public void run() {
                    System.out.println("线程测试");
                }
            });
    

    那么由于此时线程池里面没有线程,也就是线程池中线程数量为0,小于线程池设置的corePoolSize。所以线程池中会创建一个线程用来处理这个任务。

    为了方便后面描述,我们对每个任务进行编号,这个任务就叫做任务1吧。

    第二第三个任务也来了

    第二个任务过来的时候。无论一个线程是否执行完毕,这个时候第二个任务来了,因为设置的corePoolSize是3,当前线程中一共只有1个线程,所以这里会再创建一个线程,并执行任务2

    第三个任务过来的时候。无论一个线程是否执行完毕,这个时候第二个任务来了,因为设置的corePoolSize是3,当前线程中一共只有2个线程,所以这里会再创建一个线程,并执行任务3

    所有任务执行完了

    现在暂时没有任务过来了,任务123都执行完毕了,这个时候已经创建的线程都会区监听任务队列等待新任务的到来

    任务4、5、6来了

    现在突然又来一批任务,这个时候因为线程池中的线程数量已经等于corePoolSize了,所以不会创新新的线程,任务会直接加入队列中等待被某一个线程处理

  • 相关阅读:
    Mysql支持的数据类型
    JavaScript 原型中的哲学思想
    99%的人都理解错了HTTP中GET与POST的区别
    Let's Encrypt,站点加密之旅
    说说cglib动态代理
    说说Java代理模式
    RESTful API 编写指南
    RESTful 架构风格概述
    Centos 6 搭建安装 Gitlab
    超详细的阿里字节Spring面试技术点总结(建议收藏)
  • 原文地址:https://www.cnblogs.com/joimages/p/12058518.html
Copyright © 2011-2022 走看看