標籤:ora art try 初始化 string 異常 code 1.0 margin
官方文檔翻譯:
如果本線程是處於阻塞狀態:調用線程的wait(), wait(long)或wait(long, int)會讓它進入等待(阻塞)狀態,或者調用線程的join(), join(long),
join(long, int), sleep(long), sleep(long, int)也會讓它進入阻塞狀態。若線程在阻塞狀態時,調用了它的interrupt()方法,那麼
它的“中斷狀態”會被清除並且會收到一個InterruptedException異常。例如,線程通過wait()進入阻塞狀態,此時通過interrupt()中斷該線程;
調用interrupt()會立即將線程的中斷標記設為“true”,但是由於線程處於阻塞狀態,所以該“中斷標記”會立即被清除為“false”,同時,會產生一個InterruptedException的異常。
如果線程被阻塞在一個Selector選取器中,那麼通過interrupt()中斷它時;線程的中斷標記會被設定為true,並且它會立即從選擇操作中返回。
如果不屬於前面所說的情況,那麼通過interrupt()中斷線程時,它的中斷標記會被設定為“true”。中斷一個“已終止的線程”不會產生任何操作。
線程處於“阻塞狀態”和“運行狀態”的終止方式如下:
(1)使用isInterrupted判斷,使用interrupt中斷
@Overridepublic void run() { try { // 1. isInterrupted()保證,只要中斷標記為true就終止線程。 while (!isInterrupted()) { // 執行任務... } } catch (InterruptedException ie) { // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止。 }}
例子1:
package concurrentMy.interrupts;/** * * (interrupt()常常被用來終止“阻塞狀態”線程。) * * <p> * 修改曆史: <br> * 修改日期 修改人員 版本 修改內容<br> * -------------------------------------------------<br> * 2016年11月3日 下午2:56:44 user 1.0 初始化建立<br> * </p> * * @author Peng.Li * @version 1.0 * @since JDK1.7 * 運行結果:A線程的狀態: (NEW) is newA線程的狀態: (RUNNABLE) is startA線程的狀態: (RUNNABLE) loop 1A線程的狀態: (RUNNABLE) loop 2A線程的狀態: (TIMED_WAITING) is interruptedA線程的狀態: (RUNNABLE) catch InterruptedException.A線程的狀態: (TERMINATED) is interrupted now結果說明:1.主線程通過 new ThreadMy("A")建立線程t1,之後之後通過t1.start()啟動線程A。 2.線程A啟動之後,會不斷的檢查它的中斷標識,如果中斷標識為false,則休眠100ms 3.t1休眠之後,會切換到主線程main,主線程再次運行,會執行t1.interrupt();中斷A線程, A收到中斷指令後,將A線程的中斷標識設定成“false”,而且會拋出InterruptedException異常 * */class ThreadMy extends Thread { public ThreadMy(String name) { super(name); } @Override public void run() { int i = 0; try { //1. isInterrupted()保證,只要中斷標記為true就終止線程。 while (!isInterrupted()) { //線程A休眠,進入阻塞狀態 Thread.sleep(100); i++; // 返回當前線程的狀態 System.out.println(Thread.currentThread().getName() + "線程的狀態: (" + this.getState() + ") loop " + i); } } catch (InterruptedException e) { // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止。 // TODO: handle exception System.out.println(Thread.currentThread().getName() + "線程的狀態: (" + this.getState() + ") catch InterruptedException."); } }}public class Demo1_interrupt { public static void main(String[] args) { try { // 建立線程A ThreadMy t1 = new ThreadMy("A"); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is new"); // 啟動線程A t1.start(); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is start"); // 主線程休眠300毫秒,然後main線程給t1發送指令 Thread.sleep(300); t1.interrupt(); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is interrupted"); // 主線程再休眠300ms,查看A線程的狀態 Thread.sleep(300); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is interrupted now"); } catch (InterruptedException e) { e.printStackTrace(); } }}
(2)安全的終止線程,使用volatile boolean變數。
package concurrentMy.interrupts;/** * * * <p> * 修改曆史: <br> * 修改日期 修改人員 版本 修改內容<br> * -------------------------------------------------<br> * 2016年11月3日 下午2:56:44 user 1.0 初始化建立<br> * </p> * * @author Peng.Li * @version 1.0 * @since JDK1.7 * 安全的終止線程,使用volatile boolean變數。運行結果:A線程的狀態: (NEW) is newA線程的狀態: (RUNNABLE) is startA線程的狀態: (RUNNABLE) loop 1A線程的狀態: (RUNNABLE) loop 2A線程的狀態: (TIMED_WAITING) is interruptedA線程的狀態: (RUNNABLE) loop 3count3A線程的狀態: (TERMINATED) is interrupted now結果說明:1.主線程通過 new ThreadMy("A")建立線程t1,之後之後通過t1.start()啟動線程A。 2.線程A啟動之後,會不斷的檢查它的中斷標識,如果中斷標識為true,則休眠100ms 3.t1休眠之後,會切換到主線程main,主線程再次運行,會執行t1.cancel();中斷A線程, A收到中斷指令後,將A線程的中斷標識設定成“false”,清除中斷標識,而且會拋出InterruptedException異常 * * * */class ThreadMy1 extends Thread { // volatile的應用,保證線程之間對on標識的可見度,一個線程(主線程)改了標識, // 即調用A線程的cancel方法取消或者停止了任務(A線程的執行,則立即對這個線程(A線程)可見 private volatile boolean on = true; public ThreadMy1(String name) { super(name); } /** * * (// 通過on 變數來控制是否需要停止任務並且終止任務) * */ public void cancel() { on = false; } @Override public void run() { int i = 0; try { // on = false 的時候中斷線程 while (on /* && !isInterrupted() */) { // 線程A休眠,進入阻塞狀態 Thread.sleep(100); i++; // 返回當前線程的狀態 System.out.println(Thread.currentThread().getName() + "線程的狀態: (" + this.getState() + ") loop " + i); } System.out.println("count" + i); } catch (InterruptedException e) { // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止,這個地方加一些日誌操作 // TODO: handle exception System.out.println(Thread.currentThread().getName() + "線程的狀態: (" + this.getState() + ") catch InterruptedException."); } }}public class Demo2_interrupt { public static void main(String[] args) { try { // 建立線程A ThreadMy1 t1 = new ThreadMy1("A"); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is new"); // 啟動線程A t1.start(); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is start"); // 主線程休眠300毫秒,然後main線程給t1發送指令 Thread.sleep(300); // 中斷線程 t1.cancel(); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is interrupted"); // 主線程再休眠300ms,查看A線程的狀態 Thread.sleep(300); System.out.println(t1.getName() + "線程的狀態: (" + t1.getState() + ") is interrupted now"); } catch (InterruptedException e) { e.printStackTrace(); } }}
java基礎知識回顧之java Thread類學習(十二)-- 線程中斷