通常我们构建线程池一般使用这种方式 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