java的线程池是怎么实现的?
java的线程都有哪些状态?
【图解】透彻Java线程状态转换_Java知音_的博客-CSDN博客
java的线程池是怎么实现的?
线程池在内部实际上构建了一个生产者消费者模型,将线程和任务两者解耦,并不直接关联,从而良好的缓冲任务,复用线程。
任务管理部分充当生产者的角色,当任务提交后,线程池会判断该任务后续的流转:
(1)直接申请线程执行该任务;
(2)缓冲到队列中等待线程执行;
(3)拒绝该任务。
线程管理部分是消费者,它们被统一维护在线程池内,根据任务请求进行线程的分配,当线程执行完任务后则会继续获取新的任务去执行,最终当线程获取不到任务的时候,线程就会被回收。
worker线程队列.
workQueue任务管理.
java.util.concurrent.ThreadPoolExecutor
private final BlockingQueue<Runnable> workQueue;
private final HashSet<Worker> workers = new HashSet<Worker>();
线程池需要解决的问题
-
线程池如何维护自身的状态,用于让使用者知道线程池内部的运行状态?
-
线程池如何管理任务?
-
什么时候可以提交任务?
-
任务满了怎么处理?
-
-
要如何管理线程?
-
如何知道这个线程已执行完,执行中,
-
什么时候可以销毁,什么时候可以复用?
-
线程池如何维护自身状态?
线程池运行的状态,并不是用户显式设置的,而是伴随着线程池的运行,由内部来维护。线程池内部使用一个变量维护两个值:运行状态(runState)和线程数量 (workerCount)。在具体实现中,线程池将运行状态(runState)、线程数量 (workerCount)两个关键参数的维护放在了一起,如下代码所示:
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
Worker线程是怎么管理的?
线程池为了掌握线程的状态并维护线程的生命周期,设计了线程池内的工作线程Worker。
Worker线程是怎么执行任务的?
- while循环不断地通过getTask()方法获取任务。
- getTask()方法从阻塞队列中取任务。
- 如果线程池正在停止,那么要保证当前线程是中断状态,否则要保证当前线程不是中断状态。
- 执行任务。
- 如果getTask结果为null则跳出循环,执行processWorkerExit()方法,销毁线程。
线程池是怎么创建线程的?
查看源代码可以看到 在addWorker方法里
使用的Executors.defaultThreadFactory()#newThread创建出来的线程.
private boolean addWorker(Runnable firstTask, boolean core){
// ...中间省略
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
}
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
his(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
一个线程池中的线程异常了,那么线程池会怎么处理这个线程?
- 怎么处理这个线程?
当一个线程异常了,processWorkerExit方法会把这个线程从线程池中移除.,会重新addWorker一个新的线程.
- 会对其它线程有影响吗?
不会影响.
- 异常堆栈会输出吗?
-
当执行方式是execute时,可以看到堆栈异常的输出
-
当执行方式是submit时,堆栈异常没有输出。但是调用Future.get()方法时,可以捕获到异常
线程池被创建后里面有线程吗?如果没有的话,你知道有什么方法对线程池进行预热吗?
线程池可以动态调整参数吗?
线程池的大小可以动态调整,具体参见文档.
线程池的监控
线程池怎么实现监控?
用户基于JDK原生线程池ThreadPoolExecutor提供的几个public的getter方法,可以读取到当前线程池的运行状态以及参数
线程池监控有哪些维度?
线程池活跃度、
任务的执行Transaction(频率、耗时)
Reject异常
线程池内部统计信息等等
怎么实现线程池的监控?
-
统一标准 以及 agent采集,根据实际情况采集需要的数据进行监控以及动态调整。
-
简易版,启动一个线程定期采集相关的监控数据.
Spring中使用的线程池?
spring的线程池ThreadPoolTaskExecutor 是对java的ThreadPoolExecutor进行了封装处理。
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
ThreadPoolTaskExecutor 什么时候内部创建了 ThreadPoolExecutor?
可以注意到也实现了 InitializingBean 接口.
具体初始化实现类
org.springframework.scheduling.concurrent.ExecutorConfigurationSupport
@Override
public void afterPropertiesSet() {
initialize();
}
/**
* Set up the ExecutorService.
*/
public void initialize() {
if (logger.isInfoEnabled()) {
logger.info("Initializing ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
}
if (!this.threadNamePrefixSet && this.beanName != null) {
setThreadNamePrefix(this.beanName + "-");
}
this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
}
/**
* Create the target {@link java.util.concurrent.ExecutorService} instance.
* Called by {@code afterPropertiesSet}.
* @param threadFactory the ThreadFactory to use
* @param rejectedExecutionHandler the RejectedExecutionHandler to use
* @return a new ExecutorService instance
* @see #afterPropertiesSet()
*/
protected abstract ExecutorService initializeExecutor(
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler);
在ThreadPoolTaskExecutor 实现并创建了 ThreadPoolExecutor
protected ExecutorService initializeExecutor(
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
BlockingQueue<Runnable> queue = createQueue(this.queueCapacity);
ThreadPoolExecutor executor;
if (this.taskDecorator != null) {
executor = new ThreadPoolExecutor(
this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
queue, threadFactory, rejectedExecutionHandler) {
@Override
public void execute(Runnable command) {
Runnable decorated = taskDecorator.decorate(command);
if (decorated != command) {
decoratedTaskMap.put(decorated, command);
}
super.execute(decorated);
}
};
}
else {
executor = new ThreadPoolExecutor(
this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
queue, threadFactory, rejectedExecutionHandler);
}
if (this.allowCoreThreadTimeOut) {
executor.allowCoreThreadTimeOut(true);
}
this.threadPoolExecutor = executor;
return executor;
}
参考文档
一个线程池中的线程异常了,那么线程池会怎么处理这个线程? - 反光的小鱼儿 - 博客园
JAVA系列:Synchronized工作原理_NIO4444的博客-CSDN博客_java synchronized原理