线程池的实现原理和常见问题

线程池实现原理

1.线程池状态
线程池的实现原理和常见问题

runState 表示当前线程池的状态,它是一个volatile变量用来保证线程之间的可见性
static final 变量表示runState可能的几个取值
RUNNING 当创建线程池后,初始时,线程池处于RUNNING状态
SHUTDOWN 如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕
STOP 如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务
TERMINATED 当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态

2.任务的执行

在了解将任务提交给线程池到任务执行完毕整个过程之前,我们先来看一下ThreadPoolExecutor类中其他的一些比较重要成员变量:线程池的实现原理和常见问题

线程池的常见问题

1.如果你提交任务时,线程池队列已满。会时发会生什么?
事实上如果一个任务不能被调度执行那么ThreadPoolExecutor’s submit()方法将会抛出一个RejectedExecutionException异常。

2.Java线程池中submit() 和 execute()方法有什么区别?
两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线 程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。

3.volatile 关键字作用是什么?(保证原子性)
volatile是一个特殊的修饰符,只有成员变量才能使用它。volatile变量可以保证下一个读取操作会在前一个写操作之后发生。
多线程使用volatile关键字修饰的变量,保证了其在多线程之间的可见性,即每次读取到volatile变量,一定是最新的数据,用来进行原子性操作。

4.Java多线程中调用wait() 和 sleep()方法有什么不同?
Java程序中wait 和 sleep都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而 sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。

5.volatile和synchronized对比?
volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
volatile仅能实现变量的修改可见性,synchronized可以保证变量的修改可见性和原子性.
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.

Java中的ThreadPoolExecutor类

Executor 是一个顶层接口,在它里面只声明了一个方法execute(Runnable),返回值为void,参数为Runnable类型,从字面意思可以理解,就是用来执行传进去的任务的
ExecutorService ExecutorService接口继承了Executor接口,并声明了一些方法:submit、invokeAll、invokeAny以及shutDown等
AbstractExecutorService 抽象类AbstractExecutorService实现了ExecutorService接口,基本实现了ExecutorService中声明的所有方法
ThreadPoolExecutor ThreadPoolExecutor继承了类AbstractExecutorService

线程池的实现原理和常见问题

corePoolSize 核心线程池的大小。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中
maximumPoolSize 线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程
keepAliveTime 表示线程没有任务执行时最多保持多久时间会终止
unit 参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性
线程池的实现原理和常见问题
workQueue 一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择
线程池的实现原理和常见问题
threadFactory 线程工厂,主要用来创建线程
handler 表示当拒绝处理任务时的策略,有以下四种取值
线程池的实现原理和常见问题