为了了解corePoolSize和maximumPoolSize关系,先用测试代码进行测试:
第一个例子:
//使用只能5个有限队列,corePoolSize=2, maxPoolSize=10
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10,
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(5));
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
//创建15个线程
for (int i = 0; i < 15; i++) {
final int a = i;
executor.submit(() -> {
try {
Thread.sleep(500);
System.out.println(a + " --- " + executor.getQueue().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
如果创建16个线程,则有一个线程会被抛弃,
也就是:(1)可以创建最大的线程数 = 队列最大长度 + maxPoolSize, 优先使用队列,如果队列满了,才使用maxPoolSize
(2)如果使用无界队列(比如:LinkedBlockingQueue),则可以创建无穷个线程,直到内存溢出,maxPoolSize永远用不上
第二个例子:
public static void main(String[] args) {
//使用只能5个有限队列,corePoolSize=15, maxPoolSize=15
ThreadPoolExecutor executor = new ThreadPoolExecutor(15, 15,
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(5));
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
//创建15个线程
for (int i = 0; i < 20; i++) {
executor.execute(new MyThread(i));
}
executor.shutdown();
}
public static class MyThread implements Runnable {
private int flag;
private boolean inQueue;
public MyThread(int flag) {
this.flag = flag;
}
@Override
public void run() {
System.out.println("线程编号:" + getFlag() + " 是否被加入队列:" + inQueue);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public boolean isInQueue() {
return inQueue;
}
public void setInQueue(boolean inQueue) {
this.inQueue = inQueue;
}
public int getFlag() {
return flag;
}
}
如果corePoolSize=15,创建15个线程,则直接执行15个线程,无需加入队列,
如果corePoolSize=14,直接执行14个线程,1个线程进入队列
也就是:(1)进入队列的线程数量 = max(线程数-corePoolSize, 队列最大长度)
(2)直接执行的线程数量 = if(线程数量>corePoolSize and 线程数量<=队列最大长度) {
return 线程数量-corePoolSize
} else if(线程数量>队列最大长度 and 线程数量<=maxPoolSize + 队列最大长度) {
return 线程数量 - 队列最大长度
} else if(线程数量>maxPoolSize + 队列最大长度){
return 线程数量 - 队列最大长度( 其他被抛弃或报错)
}