原文链接:https://blog.csdn.net/qishiheyongshi/article/details/132155705
// 当线程数量达到corePoolSize,且workQueue队列塞满任务了之后,继续创建线程,但不能超过 maximumPoolSize
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 3,
5, TimeUnit.SECONDS, //5 秒內沒有任务要处理,非核心线程释放掉
/**
* LinkedBlockingQueue、ArrayBlockingQueue,实测执行结果没发现不同
* 队列中最多能存入的任务数量
* 当所有的核心线程都在处理任务的时候,新进来的任务将放入队列中,
* 如果队列中放满了,则新建额外的线程处理,总线程数量不能超过maximumPoolSize
* 如果队列未满,则不会新建额外线程,只使用核心线程
*/
new LinkedBlockingQueue<Runnable>(6),
Executors.defaultThreadFactory(),// 默认的线程工厂,通过 new Thread 产生线程
/**四个拒绝策略:当线程数量达到maximumPoolSize大小,并且workQueue也已经塞满了任务的情况下,线程池会调用handler拒绝策略来处理请求
* AbortPolicy:为线程池默认的拒绝策略,该策略直接抛异常处理。
* DiscardPolicy:直接抛弃不处理。
* DiscardOldestPolicy:丢弃队列中最老的任务。
* CallerRunsPolicy:将任务分配给当前执行 execute 的方法线程来处理,如这个调用方法中表示 main方法主线程。
*/
new ThreadPoolExecutor.CallerRunsPolicy());
//创建10个线程,核心线程限制性,然后放入等待队列,等待队列放满后再新建线程
for (int i = 0; i < 10; i++) {
tpe.execute(()->{
String name = Thread.currentThread().getName();
System.out.println(name);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
// System.out.println(tpe.getQueue());
//
// System.out.println(tpe.getQueue());
tpe.shutdown();
}
线程池创建的七大参数:
1、corePoolSize:线程池核心线程数量,核心线程不会被回收,即使没有任务执行,也会保持空闲状态。如果线程池中的线程少于此数目,则在执行任务时创建。
2、maximumPoolSize:当线程数量达到corePoolSize,且workQueue队列塞满任务了之后,继续创建线程,但不能超过 maximumPoolSize。
3、keepAliveTime:超过corePoolSize之后的“临时线程”的存活时间。
4、unit:keepAliveTime的单位。
5、workQueue:当线程数超过corePoolSize时,新的任务会处在等待状态,并存在workQueue中,BlockingQueue是一个先进先出的阻塞式队列实现,workQueue有以下几种实现:
(1)、ArrayBlockingQueue 基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
(2)、LinkedBlockingQuene基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
(3)、SynchronousQuene一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
(4)、PriorityBlockingQueue 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
ArrayBlockingQueue和PriorityBlockingQueue一般很少使用
6、threadFactory:创建线程的工厂类,通常我们会自定义一个threadFactory设置线程的名称,这样我们就可以知道线程是由哪个工厂类创建的,可以快速定位。
7、handler:线程池执行拒绝策略,当线程数量达到maximumPoolSize大小,并且workQueue也已经塞满了任务的情况下,线程池会调用handler拒绝策略来处理请求。