import java.io.IOException;
public class Mythread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行中...");
try {
System.in.read();
} catch (IOException e) {
System.out.println("error" + e);
}
System.out.println(Thread.currentThread().getName() + "over...");
}
}
public static void main(String[] args) throws Exception {
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 4, 2, TimeUnit.SECONDS, queue);
Mythread t1 = new Mythread();
Mythread t2 = new Mythread();
Mythread t3 = new Mythread();
Mythread t4 = new Mythread();
Mythread t5 = new Mythread();
Mythread t6 = new Mythread();
Mythread t7 = new Mythread();
poolExecutor.execute(t1);
poolExecutor.execute(t2);
poolExecutor.execute(t3);
poolExecutor.execute(t4);
poolExecutor.execute(t5);
poolExecutor.execute(t6);
poolExecutor.execute(t7);
poolExecutor.shutdown();
}
上面是我模拟使用了下ThreadPoolExecutor,下面让我们来一起了解下ThreadPoolExecutor对应的几个参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime:空闲线程能存活的最长时间
- unit:上面keepAliveTime对应的单位,分、秒等
- workQueue:等待队列
这篇文章主要想说下corePoolSize和maximumPoolSize的区别,为了搞清楚这个,接下来,让我们debug下上面的测试代码吧
1、当我们往线程池中添加第5个线程的时候,现在线程池中的状态是,正在运行的线程有两个,等待队列的任务有两个,那如果添加完第5个线程呢?
2、有没有发现好像有点意思了,现在是队列满了,才会新创建线程,继续往下走
3、现在最大线程数达到了4个,队列也有2个,也满了,接下来会发生生么呢?
4、当我们添加第7个任务时,一步步跟进去,发现走到了抛出拒绝当前这个任务的异常
综上所述:当任务大小到达coreSize大小时,任务可以正常运行,当任务个数大于coreSize的大小时,任务就先会放在等待队列中,当等待队列也放满了,接下来才会创建线程,知道当前线程数等于最大线程数,当队列也满了,也达到最大线程数了,接下来添加的任务都会被拒绝掉,直接抛出异常
注:添加任务的顺序和任务执行的顺序并不一样
public class ReduceTest {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 0, TimeUnit.MINUTES,
new ArrayBlockingQueue<>(10));
for (int i=0; i<100; ++i) {
threadPoolExecutor.execute(new Mytask(i));
}
}
}
class Mytask implements Runnable {
private int i;
public Mytask(int s) {
this.i = s;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + ": " + i);
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
上图中是执行代码的结果,从图中我们可以看出来,任务执行的顺序有点诡异,为什么9-19的任务不是先于20-29,下图中的源码可以解释这个原因
当队列满了,添加后面的任务的时候,首先先判断该任务为空么,不为空的话,直接执行
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)