JAVA线程池实现03-其余方法
shutdown安全停止任务
注意该方法不会马上停止线程池,会先将线程池置于shutdown状态然后发起中断请求,等待任务自己结束,线程内部要实现中断请求的响应处理,否则就不会终止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); advanceRunState(SHUTDOWN); interruptIdleWorkers(); onShutdown(); } finally { mainLock.unlock(); } tryTerminate(); }
|
检查权限 checkShutdownAccess
这主要的目的是为了在系统层面对线程池进行保护,防止其发生意外。比如中断系统进程等,获取了安全管理器之后接下来再对其进行权限检查。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| private void checkShutdownAccess() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission(shutdownPerm); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (ThreadPoolExecutor.Worker w : workers) { security.checkAccess(w.thread); } } finally { mainLock.unlock(); } } }
|
更改运行状态 advanceRunState
更改线程池的状态
1 2 3 4 5 6 7 8 9
| private void advanceRunState(int targetState) { for (; ; ) { int c = ctl.get(); if (runStateAtLeast(c, targetState) || ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))) break; } }
|
中断工作任务 interruptIdleWorkers
中断任务,但是只是发起中断请求,不会强制中断任务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
private void interruptIdleWorkers() { interruptIdleWorkers(false); }
private void interruptIdleWorkers(boolean onlyOne) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) { Thread t = w.thread; if (!t.isInterrupted() && w.tryLock()) { try { t.interrupt(); } catch (SecurityException ignore) { } finally { w.unlock(); } } if (onlyOne) break; } } finally { mainLock.unlock(); } }
|
尝试终止任务
尝试终止任务如果有正在运行的任务或者任务队列不为空且运行状态是SHUTDOWN就返回,不进行前置终止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
final void tryTerminate() { for (;;) { int c = ctl.get();
if (isRunning(c) || runStateAtLeast(c, TIDYING) || (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty())) { return; } if (workerCountOf(c) != 0) { interruptIdleWorkers(ONLY_ONE); return; } final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) { try { terminated(); } finally { ctl.set(ctlOf(TERMINATED, 0)); termination.signalAll(); } return; } } finally { mainLock.unlock(); } } }
|
shutdownNow马上终止线程
该方法是马上中断线程池,如果有未完成的任务先发起中断请求,然后将线程池中的任务删除,并将删除的数据放进一个临时的队列并且返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); advanceRunState(STOP); interruptWorkers(); tasks = drainQueue(); } finally { mainLock.unlock(); } tryTerminate(); return tasks; }
|
drainQueue 清空队列
清理队列并且返回未完成任务的列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
private List<Runnable> drainQueue() { BlockingQueue<Runnable> q = workQueue; ArrayList<Runnable> taskList = new ArrayList<Runnable>(); q.drainTo(taskList); if (!q.isEmpty()) { for (Runnable r : q.toArray(new Runnable[0])) { if (q.remove(r)) { taskList.add(r); } } } return taskList; }
|
shutdown与shutdownNow
到这里我们发现shutdown和 shutdownNow很像,但是有差别,shutdownNow就强制在调用后会清空任务列表,强制终止任务,但是shutdown不会,shutdown会等待任务完成然后才会进行终止。
isShutdown 线程池是否关闭
1 2 3
| public boolean isShutdown() { return ! isRunning(ctl.get()); }
|
isTerminating 线程池是否正在终止
1 2 3 4
| public boolean isTerminating() { int c = ctl.get(); return ! isRunning(c) && runStateLessThan(c, TERMINATED); }
|
线程池是否终止
1 2 3
| public boolean isTerminated() { return runStateAtLeast(ctl.get(), TERMINATED); }
|