多線程是java中很重要的知識點,在此小編給大家總結Java Thread多線程,非常有用,希望大家可以掌握哦。
方法一Thread.sleep
#方法二ExecutorService
方法三thread .join
方法四Thread.yield and Thread.activeCount
main 方法運行完畢後其他子執行緒都會關閉, 無法觀察到所有子線程的詳細的運行情況, 於是需要讓主線程等待所有子線程運行完畢後才關閉, 以前比較馬虎的做法就是在
main 函數裡面添加
Thread. sleep(time)
這應該是最常見的方法, 雖然不是最佳的實踐, 但是可以勉強滿足需求.
public static void main(String[] args) throws InterruptedException{ for(int i=0; i<10; i++){ new Thread("subthread" + i){ @Override public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }.start(); } Thread.sleep(2000); System.out.println("main thread finished"); }運行結果:
subthread0finished subthread1finished subthread2finished subthread6finished subthread4finished subthread5finished subthread3finished subthread9finished subthread8finished subthread7finished main thread finished方法二ExecutorService可以使用執行緒池實作, 常用的執行緒池物件都是
ExecutorService
介面的實作, 其中提供了shutdown 等方法可以保證目前提交的任務在子執行緒上運行完畢後Java進程正常退出.
public static void main(String[] args) { // 创建一个ExecutorService ExecutorService ex = Executors.newCachedThreadPool(); for(int i=0; i<10; i++){ // 添加 task ex.submit(new Thread("subthread" + i){ @Override public void run() { try{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }); } // 使用shutdown 会通知executorservice 停止添加其它task 它会等待所有子线程运行结束才退出Java进程 ex.shutdown(); System.out.println("main thread finished"); }
運行結果為:
main thread finished pool-1-thread-3finished pool-1-thread-4finished pool-1-thread-2finished pool-1-thread-1finished pool-1-thread-5finished pool-1-thread-7finished pool-1-thread-8finished pool-1-thread-6finished pool-1-thread-9finished pool-1-thread-10finished
此種方法有一些小的瑕疵, 我們從輸出的資訊可以看到主線程其實先於子線程運行完畢, 所以這種方法只能夠保證子線程在程序退出之前可以運行完, 但是不能夠保證主線程在子線程運行完畢之後再執行.所以代碼還需要更改,新增一個
awaitTermination(time, timeunit) 設定一個較為合理的等待的時間, 等待子執行緒運行完畢.
public static void main(String[] args) { // 创建一个ExecutorService ExecutorService ex = Executors.newCachedThreadPool(); for(int i=0; i<10; i++){ // 添加 task ex.submit(new Thread("subthread" + i){ @Override public void run() { try{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }); } // 使用shutdown 会通知executorservice 停止添加其它task 它会等待所有子线程运行结束才退出Java进程 ex.shutdown(); try { // 设置等待时间等待子线程运行完毕 if(!ex.awaitTermination(2000, TimeUnit.MILLISECONDS)){ // 等待时间内子线程并未全部运行完毕就直接关闭 ex.shutdownNow(); } }catch(InterruptedException e){ ex.shutdownNow(); } System.out.println("main thread finished"); }
運行結果:
pool-1-thread-1finished pool-1-thread-5finished pool-1-thread-4finished pool-1-thread-9finished pool-1-thread-8finished pool-1-thread-3finished pool-1-thread-2finished pool-1-thread-7finished pool-1-thread-6finished pool-1-thread-10finished main thread finished可以看到主執行緒執行的內容在最後輸出的. 這個方法與方法一一樣都需要設定等待時間, 不是很完美的方法.方法三thread.join
thread. join
表示執行這段程式碼的執行緒會處於掛起狀態, 等待呼叫這個方法的執行緒(這裡就是這個thread) 運行完畢後才繼續運行. 下面的例子中子執行緒都是在main 執行緒上面建立的, 所以在
main 執行緒裡面執行
某一個子執行緒.join 時會等待子執行緒運行完畢才繼續執行
main 執行緒, 程式碼如下:
public static void main(String[] args) throws InterruptedException{ List<Thread> list = new ArrayList<>(); for(int i=0; i<10; i++){ Thread t = new Thread("subthread" + i){ @Override public void run() { try{ Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }; list.add(t); t.start(); } for(Thread item : list){ item.join(); } System.out.println("main thread finished"); }
執行結果:
subthread1finished subthread2finished subthread0finished subthread3finished subthread6finished subthread5finished subthread4finished subthread9finished subthread7finished subthread8finished main thread finished使用這個方法相比去上面兩種方法優點在於不用設定等待時間.方法四Thread.yield and Thread.activeCount
首先說明一下這兩個方法的作用,
Thread.yield
放棄
自己佔用CPU 的權利. 但是並不表示當前線程一定不再執行.
Thread.activeCount 方法返回的是當前調用這個線程對應的線程組中所有的活躍線程數量. 在創建線程的時候(new Thread) 其中這個
ThreadGroup
參數指的就是創建線程對應的線程組, 如果這個參數沒有指定, 那麼創建的線程與創建這個線程的線程是同一個線程組. 程式碼如下:
public static void main(String[] args) { // 关键参数 int defaultThreadNum = 2; for(int i=0; i<10 ;i++){ new Thread("subthread" + i){ @Override public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "finished"); }catch(InterruptedException e){ e.printStackTrace(); } } }.start(); } while(Thread.activeCount() > defaultThreadNum){ // 当活跃线程数大于设定的默认线程数的时候 主线程让步 Thread.yield(); } System.out.println("main thread finished"); }
運行結果:
subthread0finished subthread4finished subthread1finished subthread8finished subthread9finished subthread5finished subthread2finished subthread3finished subthread6finished subthread7finished main thread finished
有一個很關鍵的地方就是這個
defaultthreadnum 設定的是2. 有一些blog中設定的是1, 但是1會導致無限循環, 主線程無法退出, 原因在於大家都認為主線程所在的線程組中排除子線程後只剩下主線程一個線程了, 其實不然, 比如我們運行如下的代碼:public static void main(String[] args) { Thread.currentThread().getThreadGroup().list(); }輸出:
java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main] Thread[Monitor Ctrl-Break,5,main]
可以看到主線程所在的線程組中還有一個叫Monitor Ctrl-Break
的線程, 因此排除所有子線程後還剩餘2個線程, 所以循環判斷的門限(defaultThreadNum) 需要設定為2.
此方法也是不需要設定等待時間的.綜上所述, 如果需要實作主執行緒在所有子執行緒運行結束後再運行可以使用方法三和方法四.
######### ######相關推薦:############Java Thread多執行緒全面解析###########php5 non -thread-safe和thread-safe的差別######以上是子執行緒任務全部完成後主執行緒關閉的四種方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

Java代碼可以在不同操作系統上無需修改即可運行,這是因為Java的“一次編寫,到處運行”哲學,由Java虛擬機(JVM)實現。 JVM作為編譯後的Java字節碼與操作系統之間的中介,將字節碼翻譯成特定機器指令,確保程序在任何安裝了JVM的平台上都能獨立運行。

Java程序的編譯和執行通過字節碼和JVM實現平台獨立性。 1)編寫Java源碼並編譯成字節碼。 2)使用JVM在任何平台上執行字節碼,確保代碼的跨平台運行。

Java性能与硬件架构密切相关,理解这种关系可以显著提升编程能力。1)JVM通过JIT编译将Java字节码转换为机器指令,受CPU架构影响。2)内存管理和垃圾回收受RAM和内存总线速度影响。3)缓存和分支预测优化Java代码执行。4)多线程和并行处理在多核系统上提升性能。

使用原生庫會破壞Java的平台獨立性,因為這些庫需要為每個操作系統單獨編譯。 1)原生庫通過JNI與Java交互,提供Java無法直接實現的功能。 2)使用原生庫增加了項目複雜性,需要為不同平台管理庫文件。 3)雖然原生庫能提高性能,但應謹慎使用並進行跨平台測試。

JVM通過JavaNativeInterface(JNI)和Java標準庫處理操作系統API差異:1.JNI允許Java代碼調用本地代碼,直接與操作系統API交互。 2.Java標準庫提供統一API,內部映射到不同操作系統API,確保代碼跨平台運行。

modularitydoesnotdirectlyaffectJava'splatformindependence.Java'splatformindependenceismaintainedbytheJVM,butmodularityinfluencesapplicationstructureandmanagement,indirectlyimpactingplatformindependence.1)Deploymentanddistributionbecomemoreefficientwi

BytecodeinJavaistheintermediaterepresentationthatenablesplatformindependence.1)Javacodeiscompiledintobytecodestoredin.classfiles.2)TheJVMinterpretsorcompilesthisbytecodeintomachinecodeatruntime,allowingthesamebytecodetorunonanydevicewithaJVM,thusfulf


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中