shutdown()方法
當使用執行緒池的時候,呼叫了shutdown()方法後,執行緒池就不會再接受新的執行任務了。但是在呼叫shutdown()方法之前放入任務佇列中的任務還是要執行的。此方法是非阻塞方法,呼叫後會立即返回,並不會等待任務佇列中的任務全部執行完畢後再返回。我們看下shutdown()方法的原始碼,如下所示。
public void shutdown() { //获取线程池的全局锁 final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //检查是否有关闭线程池的权限 checkShutdownAccess(); //将当前线程池的状态设置为SHUTDOWN advanceRunState(SHUTDOWN); //中断Worker线程 interruptIdleWorkers(); //为ScheduledThreadPoolExecutor调用钩子函数 onShutdown(); // hook for } finally { //释放线程池的全局锁 mainLock.unlock(); } //尝试将状态变为TERMINATED tryTerminate(); }
總體來說,shutdown()方法的程式碼比較簡單,首先檢查了是否有權限來關閉執行緒池,如果有權限,則再次偵測是否有中斷工作執行緒的權限,如果沒有權限,則會拋出SecurityException異常,程式碼如下所示。
//检查是否有关闭线程池的权限 checkShutdownAccess(); //将当前线程池的状态设置为SHUTDOWN advanceRunState(SHUTDOWN); //中断Worker线程 interruptIdleWorkers();
其中,checkShutdownAccess()方法的實作程式碼如下所示。
private void checkShutdownAccess() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission(shutdownPerm); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) security.checkAccess(w.thread); } finally { mainLock.unlock(); } } }
對於checkShutdownAccess()方法的程式碼理解起來比較簡單,就是偵測是否具有關閉執行緒池的權限,期間使用了執行緒池的全域鎖定。
接下來,我們來看advanceRunState(int)方法的原始碼,如下所示。
private void advanceRunState(int targetState) { for (;;) { int c = ctl.get(); if (runStateAtLeast(c, targetState) || ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))) break; } }
advanceRunState(int)方法的整體邏輯是:判斷目前執行緒池的狀態是否為指定的狀態,在shutdown()方法中傳遞的狀態是SHUTDOWN,如果是SHUTDOWN,則直接傳回;如果不是SHUTDOWN,則將目前執行緒池的狀態設為SHUTDOWN。
接下來,我們來看看showdown()方法呼叫的interruptIdleWorkers()方法,如下所示。
private void interruptIdleWorkers() { interruptIdleWorkers(false); }
可以看到,interruptIdleWorkers()方法呼叫的是interruptIdleWorkers(boolean)方法,繼續看interruptIdleWorkers(boolean)方法的原始碼,如下所示。
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(); } }
上述程式碼的總體邏輯為:取得線程池的全域鎖,循環所有的工作線程,檢測線程是否被中斷,如果沒有中斷,並且Worker線程獲得了鎖,則執行線程的中斷方法,並釋放線程獲取到的鎖。此時如果onlyOne參數為true,則退出循環。否則,循環所有的工作線程,執行相同的操作。最終,釋放線程池的全域鎖定。
接下來,我們看下shutdownNow()方法。
shutdownNow()方法
如果呼叫了執行緒池的shutdownNow()方法,則執行緒池不會再接受新的執行任務,也會將任務佇列中存在的任務丟棄,正在執行的Worker執行緒也會立即中斷,同時,方法會立刻傳回,此方法存在一個回傳值,也就是目前任務佇列中被丟棄的任務清單。
shutdownNow()方法的原始碼如下所示。
public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //检查是否有关闭权限 checkShutdownAccess(); //设置线程池的状态为STOP advanceRunState(STOP); //中断所有的Worker线程 interruptWorkers(); //将任务队列中的任务移动到tasks集合中 tasks = drainQueue(); } finally { mainLock.unlock(); } /尝试将状态变为TERMINATED tryTerminate(); //返回tasks集合 return tasks; }
shutdownNow()方法的原始程式碼的總體邏輯基本上與shutdown()方法基本上相同,只是shutdownNow()方法將線程池的狀態設為STOP,中斷所有的Worker線程,並且將任務佇列中的所有任務移動到tasks集合中並返回。
可以看到,shutdownNow()方法中斷所有的執行緒時,呼叫了interruptWorkers()方法,接下來,我們就看下interruptWorkers()方法的原始碼,如下所示。
private void interruptWorkers() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) w.interruptIfStarted(); } finally { mainLock.unlock(); } }
interruptWorkers()方法的邏輯比較簡單,就是取得線程池的全域鎖,循環所有的工作線程,依序中斷線程,最後釋放線程池的全域鎖定。
在interruptWorkers()方法的內部,實際上呼叫的是Worker類別的interruptIfStarted()方法來中斷線程,我們看下Worker類別的interruptIfStarted()方法的原始程式碼,如下所示。
void interruptIfStarted() { Thread t; if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { try { t.interrupt(); } catch (SecurityException ignore) { } } }
發現其本質上呼叫的還是Thread類別的interrupt()方法來中斷執行緒。
awaitTermination(long, TimeUnit)方法
當線程池呼叫了awaitTermination(long, TimeUnit)方法後,會阻塞呼叫者所在的線程,直到線程池的狀態修改為TERMINATED才返回,或達到了超時時間返回。接下來,我們來看看awaitTermination(long, TimeUnit)方法的原始程式碼,如下所示。
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { //获取距离超时时间剩余的时长 long nanos = unit.toNanos(timeout); //获取Worker线程的的全局锁 final ReentrantLock mainLock = this.mainLock; //加锁 mainLock.lock(); try { for (;;) { //当前线程池状态为TERMINATED状态,会返回true if (runStateAtLeast(ctl.get(), TERMINATED)) return true; //达到超时时间,已超时,则返回false if (nanos <= 0) return false; //重置距离超时时间的剩余时长 nanos = termination.awaitNanos(nanos); } } finally { //释放锁 mainLock.unlock(); } }
上述程式碼的整體邏輯為:先取得Worker執行緒的獨佔鎖,然後在迴圈判斷目前執行緒池是否已經是TERMINATED狀態,如果是則直接傳回true,否則偵測是否已經逾時,如果已經超時,則傳回false。如果未逾時,則重設距離逾時時間的剩餘時長。接下來,進入下一輪循環,再次偵測目前執行緒池是否已經是TERMINATED狀態,如果是則直接傳回true,否則偵測是否已經逾時,如果已經逾時,則傳回false。如果未逾時,則重設距離逾時時間的剩餘時長。以此循環,直到執行緒池的狀態變成TERMINATED或已經逾時。
以上是Java線程池如何優雅地實現關閉?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

Java的平台獨立性是指編寫的代碼可以在任何安裝了JVM的平台上運行,無需修改。 1)Java源代碼編譯成字節碼,2)字節碼由JVM解釋執行,3)JVM提供內存管理和垃圾回收功能,確保程序在不同操作系統上運行。

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算显著提升了Java的平台独立性。1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技術如Docker增強而非替代Java的平台獨立性。 1)確保跨環境的一致性,2)管理依賴性,包括特定JVM版本,3)簡化部署過程,使Java應用更具適應性和易管理性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 Linux新版
SublimeText3 Linux最新版