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

    这篇文章不打算讲解什么是线程池?线程池怎么用?直接讲解原理

    1、线程池关键参数解释
    JDK 线程池的实现类是 ThreadPoolExecutor,构造函数关键参数解释如下:
    corePoolSize 核心线程,线程池维持的线程数量,即使没有任务执行也会维持这个数量不变,除非设置了 allowCoreThreadTimeOut 这个参数为 true
    maximumPoolSize 线程池中允许创建线程的最大数量
    keepAliveTime 非核心线程的空闲等待时间,超过这个时间将被销毁
    unit 针对keepAliveTime 参数的时间单位
    workQueue 任务队列
     
    2、 execute和submit的区别?
    1)submit有返回值
    2)submit提交的线程类型,会被jdk包装成一个FutureTask
     
    3、运行原理
    3.1任务执行流程
    这不是一个流程图,是为了说明线程启动到执行任务的大概流程
     
    3.2 源码分析
    先说下执行主流程,再细看源码。
    执行流程:execute(Runnable command) >>addWorker(Runnable firstTask, boolean core)>>runWorker(Worker w)
    源码分析:
    1)execute(Runnable command)方法
      该方法会调用addWorker(Runnable firstTask, boolean core)方法执行任务
    2)addWorker(Runnable firstTask, boolean core) 方法
    该方法代码比较长,我们看下关键的代码部分
    既然启动线程了,那我们就去Worker里看看
    3) Worker 内部类
    既然2)中调用了start()方法,那么必然会调用Worker的 run()方法
    接下来看 runWorker(this)方法,最最关键的部分就在这里,老办法,我们也还是看最关键的代码片段
    4)看下这个方法 processWorkerExit(Worker w, boolean completedAbruptly)
                总结一下,线程池就是维护一个线程集合,用这些线程来反复的执行任务,这些线程分为核心线程和非核心线程,核心线程一般不会被销毁,就算是没有任务也会空闲等待(除了设置 allowCoreThreadTimeOut参数),非核心线程,当空闲等待时间到达设置的参数范围,就会被销毁回收。比较难理解的是JDK是如何维护线程集合并执行任务?这里在说一下,线程池初始化,当第一个任务来的时候,线程池会创建一个线程并将该线程存入一个线程集合,刚才的任务作为该线程的第一个任务执行,执行完该任务,此时线程不会立即结束,会通过getTask()方法,以阻塞等待方式从任务队列里面获取任务执行,因此如果阻塞队列有任务,就取出任务执行,如果队列没有任务,就阻塞等待任务,所以正常情况下,该线程会一直存活。当第二个任务来了以后,会执行和第一个任务同样的动作,以此类推,直到核心线程数量达到corePoolSize设置的参数数量,这样就形成了线程集合,也就是线程池。当任务很多的时候,核心线程不能及时全部处理完毕,此时线程池就会将任务存入任务队列,如果队列满了,并且 maximumPoolSize 大于 corePoolSize,就会创建非核心线程执行任务。
  • 相关阅读:
    ##日常代码中,我们需要配的几种数据源的配置文件
    ##Sping框架IOC中常用的注解大家一定要记住
    ##事务管理器工具类
    ##管理连接的工具类 用来实现连接 和线程的绑定
    ##处理转账事务的多线程问题,让其在一个线程处理账务的增加和减少
    学习笔记——spark安装配置
    学习笔记——spark基础实验二
    学习笔记——spark实验一
    课堂测试之数据清洗
    Mapreduce实例——WordCount
  • 原文地址:https://www.cnblogs.com/tspeking/p/9298067.html
Copyright © 2011-2022 走看看