一)Java构建线程的方式
1. 继承Thread
2. 实现Runnable
3. 实现Callable
4. 线程池实现(Java提供了构建线程池的方式)
java提供了Executor可以去创建(规范中不允许使用这种方式创建线程池,这种方式对线程的控制粒度比较低),建议 new ThreadPoolExecutor()
二) 线程池的7个参数
public ThreadPoolExecutor(int corePoolSize, //核心线程数量
int maximumPoolSize, // 最大线程数量
long keepAliveTime, // 最大空余时间
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //阻塞队列
ThreadFactory threadFactory, //线程工场
RejectedExecutionHandler handler)// 拒绝策略
{}
三) 线程池的执行流程
对图的一个说明:
1. 当有任务时,提交任务,在线程池中查看是否有核心线程,如果有,则执行该任务,如果没有,则把该任务放到阻塞队列中
2. 如果阻塞队列没满,则放到阻塞队列中排队,如果满了,则看线程池中的工作线程数量是否为最大线程数,如果不是,则创建非核心线程,如果是,则采取拒绝策略
四) 线程池属性标识
// AtomicInteger 是 int类型的数据,声明线程池的状态,声明线程池中的线程数
// 高三位是线程池的状态,低三位是线程池的个数
private final AtomicInteger ctl;
private static final int COUNT_BITS = 29; // Integer.size
private static final int CAPACITY = 536870911; // 最大容量
// 以下是【线程池的状态】
private static final int RUNNING = -536870912; //111代表正常接收任务
private static final int SHUTDOWN = 0; //000代表线程池为shutdown的状态,不接收新的任务,但是内部还是会处理队列中的任务,正在进行的任务正常处理
private static final int STOP = 536870912; // 001 代表线程池为stop状态。不接收新的任务,也不去处理阻塞队列中的任务,同时也会中断正在执行中的任务
private static final int TIDYING = 1073741824; // 010 代表线程池是一个过渡状态,代表当前线程池即将over
private static final int TERMINATED = 1610612736;// 011 代表线程池状态为over
// 得到线程池的状态
private static int runStateOf(int var0) {return var0 & -536870912;}
// 得到当前线程池的线程数量
private static int workerCountOf(int var0) { return var0 & 536870911;}
线程池转态变化
五)线程池的execute方法执行
public void execute(Runnable var1) {
// 健壮性的判断
if (var1 == null) {
throw new NullPointerException();
} else {
// 拿到32位的int
int var2 = this.ctl.get();
// 获取 【工作线程数】< 核心线程数
if (workerCountOf(var2) < this.corePoolSize) {
// 可以创建 【核心】 线程数
if (this.addWorker(var1, true)) {
return;
}
// 代表创建核心线程数失败,重新获取ctl
var2 = this.ctl.get();
}
// 判断线程池是否是running转态 (因为要看是否接收新任务)
// 将任务放到阻塞队列中
if (isRunning(var2) && this.workQueue.offer(var1)) {
// 再次获取ctl
int var3 = this.ctl.get();
// 再次判断是否是running状态 如果不是running,移除任务
if (!isRunning(var3) && this.remove(var1)) {
this.reject(var1); // 拒绝策略
// 获取线程池个数
// 如果线程池处于running状态,但是工作线程为0
} else if (workerCountOf(var3) == 0) {
// 阻塞队列有任务,但是没有工作线程,添加一个任务为空的工作线程处理阻塞队列中的任务
this.addWorker((Runnable)null, false);
}
// 创建非核心线程处理任务
} else if (!this.addWorker(var1, false)) {
// 拒绝
this.reject(var1);
}
}
}
查看addWorker方法
private boolean addWorker(Runnable var1, boolean var2) {
while(true) {
// 获取ctl
int var3 = this.ctl.get();
// 获取线程池状态
int var4 = runStateOf(var3);
// 除了running都有可能
if (var4 >= 0 &&
// shutdown 任务为空 阻塞队列为空
(var4 != 0 || var1 != null || this.workQueue.isEmpty())) {
// 创建工作线程失败
return false;
}
while(true) {
int var5 = workerCountOf(var3);
// 如果已经达到了线程池的最大容量,则不去创建了
// 判断是否超过核心线程
if (var5 >= 536870911 || var5 >= (var2 ? this.corePoolSize : this.maximumPoolSize)) {
return false;
}
// 将工作线程数+1 ,采用CAS的方式
if (this.compareAndIncrementWorkerCount(var3)) {
boolean var18 = false;
boolean var19 = false;
// worker就是工作线程
ThreadPoolExecutor.Worker var20 = null;
try {
var20 = new ThreadPoolExecutor.Worker(var1);
// 从工作线程中获取thread
Thread var6 = var20.thread;
if (var6 != null) {
// 获取线程池的全局锁,防止其他线程干掉这个线程池
ReentrantLock var7 = this.mainLock;
var7.lock();
try {
int var8 = runStateOf(this.ctl.get());
if (var8 < 0 || var8 == 0 && var1 == null) {
if (var6.isAlive()) {
throw new IllegalThreadStateException();
}
this.workers.add(var20);
int var9 = this.workers.size();
if (var9 > this.largestPoolSize) {
this.largestPoolSize = var9;
}
var19 = true;
}
} finally {
var7.unlock();
}
if (var19) {
var6.start();
var18 = true;
}
}
} finally {
if (!var18) {
this.addWorkerFailed(var20);
}
}
return var18;
}
var3 = this.ctl.get();
if (runStateOf(var3) != var4) {
break;
}
}
}
}