线程池是JDK1.5 引入的,JDK1.8 之后又引入更多的线程池

package java.util.concurrent;

推荐一个CSDN的好博客:https://blog.csdn.net/Youth_lql 这个人嗑了很多源码!对比我的网站人家更有料,我只是应用层的!

线程池的状态

ThreadPoolExecutor IDEA源码

Executor 音标:ɪɡˈzekjətər 一个哉 剋(特er)

runState 提供主要的生命周期控制,一个5个取值 分别是:


RUNNING:接受新任务并处理排队任务 
SHUTDOWN:不接受新任务,但处理排队任务 
STOP:不接受新任务,不处理排队任务,并中断正在进行的任务 
TIDYING:所有任务都已终止、workerCount(线程池状态)为零时,将当前状态是 TIDYING 的线程将运行 terminate() 钩子方法 
TERMINATED: 调用terminate() 方法后的终止状态



线程池有runState的说明
    private static final int COUNT_BITS = Integer.SIZE - 3;  //31

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;  //-536870912
    private static final int SHUTDOWN   =  0 << COUNT_BITS;  //0
    private static final int STOP       =  1 << COUNT_BITS;  //536870912
    private static final int TIDYING    =  2 << COUNT_BITS;  //1073741824
    private static final int TERMINATED =  3 << COUNT_BITS;  //1610612736

我们日常使用的判断即:RUNNING 大于 或者小于 0  SHUTDOWN 是否等于 0 使用 来判断线程的死活

线程池的使用Demo:

    @Test
    public void ThreadPoolTest() {
        /**
         * 配置线程池的参数 依次如下:
         * corePoolSize 核心线程数
         * maximumPoolSize 最大线程数
         * keepAliveTime 空闲线程存活时间 默认是60秒
         * 时间单位 枚举形式,选择秒即可
         * 任务阻塞队列对象 需要设定长度 有4种类: ArrayBlockingQueue和PriorityBlockingQueue使用较少,一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。
         * 工厂对象 用于创建线程 一般默认线程工厂 Executors.defaultThreadFactory() 即可
         * 线程池拒绝策略 4种,可以参考教程:https://www.zanglikun.com/8723.html#RejectedExecutor
         */
        // 创建线程池对象
        ExecutorService executorService = new ThreadPoolExecutor(3,
                5,
                60L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        // 调用线程池对象 使用Lambda执行相关操作
        for (int i = 0; i < 5; i++) {
            executorService.execute(
                    () -> {
                        System.out.println(Thread.currentThread().getName() + " >>> 正在办理业务");
                    });
        }
        // 线程池销毁 有 shutdown() 和 shutdownNow() 前者是不在接收新的任务了(线程池执行完毕所有的线程才会终止),后者停止所有线程(没执行完毕的也停止!)
        executorService.shutdown();
        //executorService.shutdownNow();
    }

结果是:

pool-1-thread-1 >>> 正在办理业务
pool-1-thread-3 >>> 正在办理业务
pool-1-thread-2 >>> 正在办理业务
pool-1-thread-3 >>> 正在办理业务
pool-1-thread-1 >>> 正在办理业务
......
看到线程ID 就知道了已经是多线程执行的了!

线程池状态之间的转换

线程池内的线程越多越好嘛?

不是,线程池的线程越多,CPU切换线程的消耗会更多上下文切换!但线程多了肯定比少了好!

线程池参数设置 建议

工作线程的取值范围

  • 如果任务是CPU密集型配置:工作线程 = cpu核心数 + 1;
  • 如果任务是IO密集型场景:工作线程 = cpu核心数 * 2;

工作线程参数,仅供面试,不可作为实际开发使用。因为线上服务器CPU种类不好区分,线上环境的线程可能有其他有应用抢占。

所以:如果是4核心CPU,那么线程池的配置 核心线程 4 最大线程数是 5

看到这里就可以看 第二篇教程了!:https://www.zanglikun.com/8813.html