通常我们构建线程池一般使用这种方式 ExecutorService executorService = Executors.newFixedThreadPool(4);//固定线程池
但是阿里开发手册上面建议使用以下方式
ThreadPoolExecutor(int corePoolSize, //核心线程池 int maximumPoolSize, //最大线程池 long keepAliveTime, //超时时间 TimeUnit unit, //时间单位 BlockingQueue<Runnable> workQueue, //队列 ThreadFactory threadFactory, //线程工厂 RejectedExecutionHandler handler) //拒绝策略
其实两种构建线程池的方式并没有什么本质的区别,阿里推荐的方式只是为了让线程池构建清楚的知道线程池的参数,避免过度内存开销和浪费 线程池五种状态
下面我们就分析下线程池工作的流程
executorService.execute(new Thread());
executorService.shutdown();
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//如果工作线程数小于核心线程数,新建一个核心线程执行任务
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
////2.核心池已满,但任务队列未满,添加到队列中
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//再次检查线程池的状态,移除队列,拒绝任务reject
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
//新建线程
addWorker(null, false);
}
//核心池已满,队列已满,试着创建一个新线程(最大线程数-核心线程数)
else if (!addWorker(command, false))
//失败 ,执行拒绝策略
reject(command);
}
ctl是什么?它贯穿了整个线程池
//ctl贯穿了整个线程池
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
private static final int COUNT_BITS = Integer.SIZE - 3;//29
//将 1 的二进制向左位移29位,再减 1 表示最大线程容量00011111111111111111111111111111
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
//接受新任务并执行队列中的任务 11100000000000000000000000000000
private static final int RUNNING = -1 << COUNT_BITS;
//不接受新任务,执行队列中的任务 00000000000000000000000000000000
private static final int SHUTDOWN = 0 << COUNT_BITS;
//不接收新任务,不执行队列中的任务,中断正在执行中的任务 00100000000000000000000000000000
private static final int STOP = 1 << COUNT_BITS; //所有的任务都已结束,线程数量为0,处于改状态的线程池即将调用terminated()方法
// 01000000000000000000000000000000
private static final int TIDYING = 2 << COUNT_BITS;
//terminated()方法执行完成
// 01100000000000000000000000000000
private static final int TERMINATED = 3 << COUNT_BITS;
//RUNNING -1左移29位
//-1的二级制表示? 负数的二进制 是正数的反码再+1(即补码)
// 1的二进制 00000000000000000000000000000001
// 反码 11111111111111111111111111111110
//-1的二进制 11111111111111111111111111111111
//左移29位 11100000000000000000000000000000
//ctl 二进制的值 | 0 得到的结果仍然是 11100000000000000000000000000000
addworker方法就是增加工作线程
//增加工作线程
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {//自旋
int c = ctl.get();
int rs = runStateOf(c);
//如果state状态大于等于SHUTDOWN,并且!(state状态等于SHUTDOWN,firstTask为空,队列不为空)
//上面是什么意思?线程已经被shutdown,但是如果队列里面还有任务,可以添加新线程来处理任务,反之一 //个条件不满足,则 return false
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
//工作线程数大于等于核心线程或者最大线程return false,core为true代表添加的核心线程,反之
return false;
if (compareAndIncrementWorkerCount(c))//cas操作工作线程+1
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs) //如果此时ctl发生变化,重新自旋
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
/*---------------------------------------------------------------上面为了工作线程+1,下面真正的new Worker()-------------------------------*/
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();//加锁,防止并发
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
//此时线程已经启动直接抛出异常
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();//开始执行工作线程
workerStarted = true;
}
}
} finally {
if (! workerStarted)
//如果失败 workers.remove(w);decrementWorkerCount(),取消上面操作,类似于事务回滚
addWorkerFailed(w);
}
return workerStarted;
}
如果addworker过程中失败了,执行addWorkerfFailed方法
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
workers.remove(w);
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
}
Worker本身又是什么?
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
private static final long serialVersionUID = 6138294804551838833L;
final Thread thread; //工作线程执行task
Runnable firstTask; //任务线程
volatile long completedTasks; //已经完成的任务数
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
public void run() {
//工作线程执行
runWorker(this);
}
protected boolean isHeldExclusively() {
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
runWorker方法
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
//如果工作线程里面的任务不为空,或者队列里面的任务不为空,一直while循环执行任务task.run();
while (task != null || (task = getTask()) != null) {
//这里上锁并不是为了并发,为了在 shutdown()时不终止正在运行的 worker
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
//前置处理器,线程池本身没有实现
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
//后置处理器,线程池本身没有实现
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
processWorkerExit方法
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}
getTask方法作用:从队列中获取任务
//从队列中获取任务
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//线程池已经被shutdown并且(STOP或者队列为空)
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
//allowCoreThreadTimeOut如果为true则代表超时时间对核心线程池也有用,即核心线程池也能被回收
//wc > corePoolSize代表操作最大线程数回收该线程
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
//(核心线程或者最大线程)timeout取队列
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
//阻塞方法(核心线程),阻塞取队列
workQueue.take();
if (r != null)
return r;
timedOut = true;//代表队列中没有待运行的任务了,进入下一次循环的时候 timed && timedOut 为true,并且workQueue.isEmpty()也是true,就会return null,线程被回收
} catch (InterruptedException retry) { timedOut = false; } } }
线程池提供的 四大拒绝策略
/**
* 调用线程执行任务
*/
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
/**
* throw异常
*/
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
/**
* 直接丢弃,啥也不干
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
/**
* 丢弃最老的任务
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
使用线程池的优点
1.重用线程池的线程,避免因为线程的创建和销毁锁带来的性能开销
2.有效控制线程池的最大并发数,避免大量的线程之间因抢占系统资源而阻塞
3.能够对线程进行简单的管理,并提供一下特定的操作如:可以提供定时、定期、单线程、并发数控制等功能
来源:https://www.cnblogs.com/dyg0826/p/10979463.html