『壹』 java中如何停止一個線程
終止線程的三種方法:1. 使用退出標志,使線程正常退出,也就是當run方法完成後線程終止。 2. 使用stop方法強行終止線程(這個方法不推薦使用,因為stop和suspend、resume一樣,也可能發生不可預料的結果)。3. 使用interrupt方法中斷線程。 1. 使用退出標志終止線程 當run方法執行完後,線程就會退出。但有時run方法是永遠不會結束的。如在服務端程序中使用線程進行監聽客戶端請求,或是其他的需要循環處理的任務。在這種情況下,一般是將這些任務放在一個循環中,如while循環。如果想讓循環永遠運行下去,可以使用while(true){……}來處理。但要想使while循環在某一特定條件下退出,最直接的方法就是設一個boolean類型的標志,並通過設置這個標志為true或false來控制while循環是否退出。下面給出了一個利用退出標志終止線程的例子。
package chapter2; public class ThreadFlag extends Thread { public volatile boolean exit = false; public void run() { while (!exit); } public static void main(String[] args) throws Exception { ThreadFlag thread = new ThreadFlag(); thread.start(); sleep(5000); // 主線程延遲5秒 thread.exit = true; // 終止線程thread thread.join(); System.out.println("線程退出!"); } }
在上面代碼中定義了一個退出標志exit,當exit為true時,while循環退出,exit的默認值為false.在定義exit時,使用了一個Java關鍵字volatile,這個關鍵字的目的是使exit同步,也就是說在同一時刻只能由一個線程來修改exit的值, 2. 使用stop方法終止線程 使用stop方法可以強行終止正在運行或掛起的線程。我們可以使用如下的代碼來終止線程: thread.stop(); 雖然使用上面的代碼可以終止線程,但使用stop方法是很危險的,就象突然關閉計算機電源,而不是按正常程序關機一樣,可能會產生不可預料的結果,因此,並不推薦使用stop方法來終止線程。 3. 使用interrupt方法終止線程 使用interrupt方法來終端線程可分為兩種情況: (1)線程處於阻塞狀態,如使用了sleep方法。 (2)使用while(!isInterrupted()){……}來判斷線程是否被中斷。 在第一種情況下使用interrupt方法,sleep方法將拋出一個InterruptedException例外,而在第二種情況下線程將直接退出。下面的代碼演示了在第一種情況下使用interrupt方法。
package chapter2; public class ThreadInterrupt extends Thread { public void run() { try { sleep(50000); // 延遲50秒 } catch (InterruptedException e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws Exception { Thread thread = new ThreadInterrupt(); thread.start(); System.out.println("在50秒之內按任意鍵中斷線程!"); System.in.read(); thread.interrupt(); thread.join(); System.out.println("線程已經退出!"); } }
上面代碼的運行結果如下: 在50秒之內按任意鍵中斷線程! sleep interrupted 線程已經退出! 在調用interrupt方法後, sleep方法拋出異常,然後輸出錯誤信息:sleep interrupted. 注意:在Thread類中有兩個方法可以判斷線程是否通過interrupt方法被終止。一個是靜態的方法interrupted(),一個是非靜態的方法isInterrupted(),這兩個方法的區別是interrupted用來判斷當前線是否被中斷,而isInterrupted可以用來判斷其他線程是否被中斷。因此,while (!isInterrupted())也可以換成while (!Thread.interrupted())。
『貳』 Java中如何終止運行中的線程while(true){i++;}死循環是如何跳出的
Java中,終止線程通常意味著在線程處理任務完成之前停止當前操作。有三種方法可以終止正在運行的線程:
首先,可以使用volatile標志位。創建一個Runnable介面的實現類,其中定義一個volatile標志位,利用這個標志位控制線程的運行。在main方法中創建線程,適當時候修改標志位以終止線程。
其次,可以使用interrupt()方法中斷線程。調用interrupt()方法在當前線程中打一個停止標記,並非立即終止線程,而是通知目標線程希望其終止。目標線程收到通知後會自行決定如何處理,如果忽略中斷,需要添加判斷邏輯以確保線程在中斷後停止。
第三,可以使用Thread的isInterrupted()方法來檢查線程是否被中斷。在關鍵代碼塊中,如sleep()或wait()操作前,先判斷是否被中斷,然後添加相應的中斷處理代碼。這種方式在遇到阻塞操作時尤為有用。
需要注意的是,調用Thread.sleep()方法時,如果線程被中斷,會拋出InterruptedException異常。這時需要捕獲這個異常,並清除中斷標記以繼續處理。
然而,Java不推薦使用stop()方法來終止線程,因為該方法可能立即停止線程的運行,導致未完成的清理工作、數據不一致等問題。此外,stop()方法已被標記為已過時。
總結,終止Java線程的方法包括使用volatile標志位、調用interrupt()方法並檢查中斷狀態、以及在關鍵操作前判斷是否被中斷。應避免使用stop()方法,以防止潛在的不安全和數據一致性問題。
『叄』 java線程關閉時會執行結束線程的方法嗎
在Java服務正常關閉或重啟時,未執行完的線程會被中止。但是,這並不意味著線程會立即終止或丟失。在一個正常關閉或重啟的過程中,Java虛擬機會嘗試以一種安全的方式停止所有的線程。
正常關閉:
當你調用System.exit()或者通過其他方式(例如:在Spring Boot應用中使用/shutdown端點)正常關閉應用時,Java虛擬機會嘗試停止所有的非守護線程。如果線程在合理的時間內沒有響應停止請求,那麼Java虛擬機會使用更強硬的手段來停止它們。
你可以通過在線程上調用Thread.interrupt()方法來中斷線程。這將設置線程的中斷狀態,如果線程處於阻塞、等待、睡眠或佔用狀態,那麼它將拋出InterruptedException。
如果你的應用有未完成的業務邏輯,通常的做法是確保這些線程在完成當前任務後可以優雅地停止。例如,如果你的線程正在處理資料庫操作,你可能希望在線程停止之前確保所有的資料庫事務都已完成。
重啟:
重啟通常涉及到停止當前運行的Java進程並啟動一個新的進程。這通常通過你的操作系統或腳本(如systemd、supervisord、upstart等)來完成。
在重啟期間,所有未完成的線程將被中止。然而,如果你的應用在重啟前可以確保所有的線程都已完成或可以安全地中止,那麼這通常不會造成問題。
在處理需要長時間運行的任務或在重啟前需要清理資源(如資料庫連接)的情況時,要確保你的代碼可以優雅地處理這些場景。
未執行完的線程:
如果Java應用在關閉或重啟時還有未執行完的線程,Java虛擬機會嘗試停止它們。這意味著這些線程將被中止,並且不會完成它們的任務。
這可能會導致未完成的數據處理、資料庫事務或其他業務邏輯被丟失。因此,重要的是要確保你的應用可以安全地處理這些線程的停止。
在一些情況下,你可能需要使用持久化機制(如資料庫、消息隊列等)來確保即使在應用關閉或重啟後,數據也不會丟失。
總的來說,Java服務在關閉或重啟時會嘗試以一種安全的方式停止所有的線程。但是,你仍然需要確保你的代碼可以優雅地處理線程的停止,並確保任何未完成的業務邏輯在關閉或重啟過程中被正確處理。