线程池的创建
ThreadPoolExecutor类的实现
ThreadPoolExecutor()构造函数的7个参数
- int corePooSize:核心线程池的大小,一开始初始化后的线程池的基本核心线程数量
- int maximumPoolSize: 线程池允许的最大线程池数,也是线程池峰值时的最大值。实际上该值并非设置多大,线程池中的线程数就能达到多大,该值与机器性能及系统有关
- long keepAiveTime:线程中线程中的允许空闲的时间。如果超过这个数值,线程一般可能会被种终止。特别实在目前线程池中的线程数量已经超过了corepoolsize规定的值时,会有部分线程被拿出来与keepAliveTime进行空闲时间对比,如果超时了则终止该线程。
- TimeUint unit : TimeUint枚举类中的时间常量,有SECONDS,MINUTES,HOURS,即时分秒等多种时间单位可以选择。
- BlockingQueue<Runnable> workQueue:排队的策略,是线程中等待工作的队列吗,其一般用于线程阻塞的情况时存储等待执行任务。
- ThreadFactory threadFactory: 用于创建线程池中线程的工厂类。其内部通过addWorker()方法来新增线程。所有调用方都必须为调用addWorker()方法做好失败的准备,因为调用该方法时,可能受线程池的策略及线程数的限制
- RejectedExecutionHandler handler:拒绝的策略,拒绝任务时的把控处理类
通过ThreadPoolExecutor类创建一个线程池threadPool01,并规定线程池的核心线程数为3,允许最大线程数为5,线程池中的每一个线程的keepAlive时间为0.5s,排队的任务队列为5。
public class DoWork implements Runnable {
private int sequence;
public DoWork(int num){
this.sequence = num;
}
@Override
public void run() {
System.out.println("Hi~~,我是"+sequence+"号任务");
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor threadPool01 = new ThreadPoolExecutor(3,5,500,
TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
for(int i = 0 ; i < 10 ;i++){
DoWork doWork = new DoWork(i);
threadPool01.execute(doWork);
System.out.println("Hi,我是线程池,目前池内线程总数量为:"+threadPool01.getPoolSize()+
", BlockingQueue中等待执行的任务为:"+threadPool01.getQueue().size());
}
for(int i = 0 ; i < 8 ; i++){
System.out.println("Hi,我是01号线程池,目前池内线程总数量为:"+threadPool01.getPoolSize()+
",BlockingQueue中等待执行的任务为:"+threadPool01.getQueue().size());
Thread.currentThread().sleep(100);
}
threadPool01.shutdown();
}
}
// 结果
Hi,我是线程池01,目前池内线程总数量为:1, BlockingQueue中等待执行的任务为:0
Hi~~,我是0号任务
Hi,我是线程池01,目前池内线程总数量为:2, BlockingQueue中等待执行的任务为:0
Hi,我是线程池01,目前池内线程总数量为:3, BlockingQueue中等待执行的任务为:0
Hi,我是线程池01,目前池内线程总数量为:3, BlockingQueue中等待执行的任务为:1
Hi,我是线程池01,目前池内线程总数量为:3, BlockingQueue中等待执行的任务为:2
Hi,我是线程池01,目前池内线程总数量为:3, BlockingQueue中等待执行的任务为:3
Hi,我是线程池01,目前池内线程总数量为:3, BlockingQueue中等待执行的任务为:4
Hi,我是线程池01,目前池内线程总数量为:3, BlockingQueue中等待执行的任务为:5
Hi,我是线程池01,目前池内线程总数量为:4, BlockingQueue中等待执行的任务为:5
Hi~~,我是1号任务
Hi,我是线程池01,目前池内线程总数量为:5, BlockingQueue中等待执行的任务为:5
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:5
Hi~~,我是2号任务
Hi~~,我是8号任务
Hi~~,我是9号任务
Hi~~,我是3号任务
Hi~~,我是4号任务
Hi~~,我是5号任务
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:2
Hi~~,我是6号任务
Hi~~,我是7号任务
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:0
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:0
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:0
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:0
Hi,我是01号线程池,目前池内线程总数量为:5,BlockingQueue中等待执行的任务为:0
Hi,我是01号线程池,目前池内线程总数量为:3,BlockingQueue中等待执行的任务为:0
Process finished with exit code 0
通过第一个for循环可以看出,在往线程池中execute线程的时候,只有当核心线程数满的时候,也就是到达3的时候才会去向BlockingQueue中添加待执行的线程,当它也满的时候才会增加工作线程数直至达到最大值5。当他们都为最大值的时候(目前池内线程总数量为:5, BlockingQueue中等待执行的任务为:5),就会使用某种RejectedExecutionHandler类中的策略,拒绝新任务的添加。
当线程池中的工作线程逐步运行了一部分任务时,任务排队队列中的任务又会放入到线程池中运行。随着任务的完成,线程的工作线程数又会逐步由最大的线程5下降到核心线程数3,然后会继续保持核心线程数3,等待以后的新增任务
newFixedThreadPool的实现
更简洁的实现方式,只用设置最大的工作线程数量
public class SampleThread {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
for(int i = 0 ; i < 10 ; i++){
DoWork doWork = new DoWork(i);
fixedThreadPool.execute(doWork);
}
}
}
Hi~~,我是1号任务
Hi~~,我是2号任务
Hi~~,我是0号任务
Hi~~,我是3号任务
Hi~~,我是5号任务
Hi~~,我是4号任务
Hi~~,我是6号任务
Hi~~,我是7号任务
Hi~~,我是8号任务
Hi~~,我是9号任务