在做练习的时候出现了下面的状况
注:只是自己的推理哈,如果后面学会了看源码再补充和修改
首先复习两个知识:
-
临时线程什么时候创建?
新任务提交时,发现核心线程都在忙、任务队列满了、并且还可以创建临时线程,此时会创建临时线程。
-
什么时候开始拒绝新的任务?
核心线程和临时线程都在忙、任务队列也满了、新任务过来时才会开始拒绝任务。
public class TestThreadPoolExecutor {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1, // 核心线程数
3, // 最大线程数
1, // 临时线程允许空闲的时间
TimeUnit.NANOSECONDS, // 时间单位
new ArrayBlockingQueue<>(3), // 阻塞队列的长度 默认为Integer.MAX
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy() // 处理策略 线程不够的时候主线程加入
);
// 执行16次
for (int i = 1; i <= 16; i++) {
// 执行16次任务
pool.execute(new MyRunnable(i));
}
pool.shutdown();
}
}
// 定义任务
class MyRunnable implements Runnable {
private int i;
public MyRunnable(int i) {
this.i = i;
}
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 执行了任务" + i);
}
}
控制台结果:
pool-1-thread-3 执行了任务6
pool-1-thread-2 执行了任务5
main 执行了任务7
pool-1-thread-1 执行了任务1
pool-1-thread-3 执行了任务2
pool-1-thread-2 执行了任务3
pool-1-thread-2 执行了任务9
pool-1-thread-3 执行了任务8
main 执行了任务10
pool-1-thread-1 执行了任务4
pool-1-thread-1 执行了任务11
pool-1-thread-5 执行了任务16 // 我最大的线程数 maximumPoolSize等于3为啥出现了第五个,第四个线程?
pool-1-thread-4 执行了任务14
pool-1-thread-5 执行了任务13
pool-1-thread-1 执行了任务12
pool-1-thread-4 执行了任务15
Process finished with exit code 0
刚开始的很是迷惑?啥情况,但是后来又想了想,可能是下面的情况
首先看到创建线程池的构造器的第三个参数为,1
,第四个为TimeUnit.NANOSECONDS
,也就是说1纳秒的时间,但是一般的计算机都是毫秒级别的。通过代码可以看到当有四个任务需要执行的时候,并且发现没有多的线程,此时就会去创建线程3,这个时候因为第七个参数,处理策略的原因主线程也加入进来。 又因为CPU是抢占式,所以顺序就不固定了,这里很好解释。但是第三和第四个参数设置的时间很短,这个时候创建出来的第三个线程就会销毁,然后最大线程数就会 maximumPoolSize - - ,问题应该就出在这个时候,此时的两个核心线程在工作,并且阻塞队列满了就会创建新的线程。就会去创建新的线程,这个时候如果这个方法没有实现线程同步,就会出现线程安全问题
,即当上一个还没有 - - 之前就会出现此时已经进行了 maximumPoolSize++
的操作 ,所以这个时候如果如果又抢到了cpu资源用于打印,这个时候就会出现线程4和线程5。当多个cpu多核处理的时候,如果线程没有同步的情况,就会出现这样的问题。
找了半天不知道是不是下面的地方没有实现线程同步:如果不是的话肯定有一个位置在做++操作的时候,没有实现同步,所以才导致的这个情况。
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
标签:thread,maximumPoolSize,任务,线程,大于,执行,pool
From: https://www.cnblogs.com/yfs1024/p/17205378.html