首先,由图可以看出:
1.execute一个线程时,线程池内数量 < corePoolSize时,直接启动一个核心线程执行任务;
2.execute一个线程时,线程池内数量 >= corePoolSize,workQueue未满时,线程放入workQueue等待执行;
3.execute一个线程时,线程池内数量 >= corePoolSize,workQueue已满,线程池内数量 < maximumPoolSize时,启动一个非核心线程执行任务;
4.execute一个线程时,线程池内数量 >= corePoolSize,workQueue已满,线程池内数量 >= maximumPoolSize时,调用RejectedExecutionHandler抛出RejectedExecutionException;
再来看看代码:
private void threadTest() {
final String TAG = "ThreadPoolExecutor test";
int corePoolSize = 5;
int maximumPoolSize = 10;
int workQueueSize = 100;
if (executor == null) {
executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(workQueueSize));
}
for (int i = 0; i < 50; i++) {
final int finalI = I;
executor.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG, "thread name:" + Thread.currentThread().getName() + " index:" + finalI
+ " hashCode: " + Thread.currentThread().hashCode());
}
});
}
}
1.当corePoolSize = 5,workQueue Size = 100,maximumPoolSize = 10;
for循环,execute 50个线程,
前5个,创建核心线程执行任务,剩下50 - 5 = 45,因为workQueue Size = 100,未满,所以剩下45个将放入workQueue等待执行;
运行结果:每2s执行5条线程,即打印5条Log;
2.改一下条件,当corePoolSize = 5,workQueue Size = 40,maximumPoolSize = 10;
for循环,execute 50个线程,
前5个,创建核心线程执行任务,剩下50 - 5 = 45,因为workQueue Size = 40,放入workQueue 40个,workQueue满了,剩下45 - 40 = 5个,这时,当前已经有核心线程5个,也就是当前线程池数量为5 < maximumPoolSize 10, 所以会开启5个非核心线程执行任务,这5个非核心线程也会执行workQueue的任务;
运行结果:每2s执行10条线程,即打印10条Log;
3.再改一下条件,当corePoolSize = 5,workQueue Size = 40,maximumPoolSize = 10;
for循环,execute 51个线程,
前5个,创建核心线程执行任务,剩下51 - 5 = 46,因为workQueue Size = 40,放入workQueue 40个,workQueue满了,剩下46 - 40 = 6个,这时,当前已经有核心线程5个,也就是当前线程池数量为5 < maximumPoolSize 10, 所以会开启5个非核心线程执行任务,然后剩下6 - 5 = 1个,而此时线程池内数量已为10,剩下的1个超出了maximumPoolSize,所以会抛出RejectedExecutionException;
运行结果:抛出RejectedExecutionException;
注意注意注意,以下很重要:
1. 第1种情况时,因为corePoolSize = 5,workQueue未满,所以池里从始至终都是这5条线程作为核心线程;
2. 第2种情况时,出现了非核心线程,也就是说线程总数大于corePoolSize,执行完任务后,池的大小会维护在corePoolSize的数量,不管原来是核心线程还是非核心线程,留在池内的就成为核心线程,多出的线程就会被回收销毁,所以池内的核心线程并不一定是原来的核心线程,也就是说,其实所有的线程都是一样的,没有特殊标明哪条是核心线程,哪条是非核心线程,最后幸存下来的就是核心线程!可以使用上边的代码打印日志观察hashCode。
————————————————
版权声明:本文为CSDN博主「bug猎手」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hanye2020/article/details/107686887
网友评论