1.线程池的构造方法
-
-
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
创建一个新的
ThreadPoolExecutor
与给定的初始参数和默认线程工厂和拒绝执行处理程序。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
创建一个新的
ThreadPoolExecutor
与给定的初始参数和默认线程工厂。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
创建一个新的
ThreadPoolExecutor
与给定的初始参数和默认拒绝执行处理程序。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
创建一个新
ThreadPoolExecutor
给定的初始参数。
-
corePoolSize | 指定线程池核心大小 |
maximumPoolSize | 指定最大线程池大小 |
keepAliveTime | 时长大小 (指定线程池空闲的 最大存活时间) |
Unit | 时长大小单位 |
workQueue | 工作队列的阻塞队列 |
threadFactory | 创建工作者线程的线程工厂 |
handler | 拒绝策略(提供四种默认, 也可自定义) |
2.执行说明
1.客户端每提交一个任务线程池就创建一个工作者线程执行任务,当达到核心线程数时,新来的任务会被存入到队列之中。线程池将任务存入工作队列时候调用的是BlockingQueue的非阻塞方法offer(E e),因此工作队列满了,也不会暂停客户端提交的线程。
2.如果没传递自己编写的ThreadFactory,那么会默认调用Executors.defaultThreadFactory()返回的默认线程工厂。当线程池饱和时,即工作线程队列满并且当前线程池大小达到最大线程池大小的情况下,客户端试图提交时会被拒绝。java标准库提供了接口用于实现RejectedExecutionHandler接口
void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
r 代表被拒绝的任务
executor 代表被拒绝任务的线程池实例
3.ThreadPoolExecutor执行顺序
线程池按以下行为执行任务
(1)当线程数小于核心线程数时,创建线程。
(2)当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
(3)当线程数大于等于核心线程数,且任务队列已满
1)若线程数小于最大线程数,创建线程
2)若线程数等于最大线程数,抛出异常,拒绝任务
参考网址:https://blog.csdn.net/wojiaolinaaa/article/details/51345789(如何设置队列大小合理)
4.参考demo
package com.licl.study.threadpool;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
int corn = Runtime.getRuntime().availableProcessors();
int maxThreadNumbers = Runtime.getRuntime().availableProcessors() * 2;
System.out.println("corn : " + corn);
System.out.println("maxThreadNumbers: " + maxThreadNumbers);
corn = 1;
maxThreadNumbers = 6;
System.out.println("corn after: " + corn);
System.out.println("maxThreadNumbers after: " + maxThreadNumbers);
//start,拒绝策略 这里没有用到。我用的是自定义的也就是实现接口复写一个就行,比如打印文字作为标记
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();
//end
ThreadPoolExecutor threadPoolExecutor
= new ThreadPoolExecutor(corn, maxThreadNumbers,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(2)
,new MyRejectedExecutionHandler());
for (int i = 1; i <= 6; i++) {
int a = i;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.currentThread().setName("thread----------0" + a);
System.out.println(Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(5);
if (a % 2 == 0) {
return;
}
if (a ==1) {
return;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
threadPoolExecutor.execute(thread);
}
while (true) {
TimeUnit.SECONDS.sleep(4);
//corn = 1
//maxThreadNubers = 6
System.out.println("返回池中当前的线程数 :" + threadPoolExecutor.getPoolSize());
System.out.println("返回正在执行任务的线程的大概数量 :" + threadPoolExecutor.getActiveCount());
System.out.println("返回在池中同时进行的最大线程数 :" + threadPoolExecutor.getLargestPoolSize());
System.out.println("返回允许的最大线程数 :" + threadPoolExecutor.getMaximumPoolSize());
BlockingQueue<Runnable> queue = threadPoolExecutor.getQueue();
System.out.println("queue大小 :" + queue.size());
}
}
}
package com.licl.study.threadpool;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("拒绝处理线程的线程:"+r);
}
}