日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程系列--“基础篇”09之 interrupt()和线程终止方式

發布時間:2024/9/5 java 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程系列--“基础篇”09之 interrupt()和线程终止方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概要

本章,會對線程的interrupt()中斷和終止方式進行介紹。涉及到的內容包括:
1. interrupt()說明
2. 終止線程的方式
? 2.1 終止處于“阻塞狀態”的線程
? 2.2 終止處于“運行狀態”的線程
3. 終止線程的示例
4. interrupted() 和 isInterrupted()的區別

1. interrupt()說明

在介紹終止線程的方式之前,有必要先對interrupt()進行了解。
關于interrupt(),java的djk文檔描述如下:http://docs.oracle.com/javase/7/docs/api/

Interrupts this thread. Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.If none of the previous conditions hold then this thread's interrupt status will be set.Interrupting a thread that is not alive need not have any effect.

大致意思是:

interrupt()的作用是中斷本線程。 本線程中斷自己是被允許的;其它線程調用本線程的interrupt()方法時,會通過checkAccess()檢查權限。這有可能拋出SecurityException異常。 如果本線程是處于阻塞狀態:調用線程的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”。 中斷一個“已終止的線程”不會產生任何操作。

?

2. 終止線程的方式

Thread中的stop()和suspend()方法,由于固有的不安全性,已經建議不再使用!
下面,我先分別討論線程在“阻塞狀態”和“運行狀態”的終止方式,然后再總結出一個通用的方式。

2.1 終止處于“阻塞狀態”的線程

通常,我們通過“中斷”方式終止處于“阻塞狀態”的線程。
當線程由于被調用了sleep(), wait(), join()等方法而進入阻塞狀態;若此時調用線程的interrupt()將線程的中斷標記設為true。由于處于阻塞狀態,中斷標記會被清除,同時產生一個InterruptedException異常。將InterruptedException放在適當的為止就能終止線程,形式如下:

1 @Override 2 public void run() { 3 while (true) { 4 try { 5 // 執行任務... 6 } catch (InterruptedException ie) { 7 // InterruptedException在while(true)循環體內。 8 // 當線程產生了InterruptedException異常時,while(true)仍能繼續運行!需要手動退出 9 break; 10 } 11 } 12 } View Code

說明:上面的InterruptedException異常的捕獲在whle(true)之內。當產生InterruptedException異常時,被catch處理之外,仍然在while(true)循環體內;要退出while(true)循環體,需要額外的執行退出while(true)的操作。

2.2 終止處于“運行狀態”的線程

通常,我們通過“標記”方式終止處于“運行狀態”的線程。其中,包括“中斷標記”和“額外添加標記”。
(01) 通過“中斷標記”終止線程。
形式如下:

1 @Override 2 public void run() { 3 while (!isInterrupted()) { 4 // 執行任務... 5 } 6 } View Code

說明:isInterrupted()是判斷線程的中斷標記是不是為true。當線程處于運行狀態,并且我們需要終止它時;可以調用線程的interrupt()方法,使用線程的中斷標記為true,即isInterrupted()會返回true。此時,就會退出while循環。
注意:interrupt()并不會終止處于“運行狀態”的線程!它會將線程的中斷標記設為true。

(02) 通過“額外添加標記”。
形式如下:

1 private volatile boolean flag= true; 2 protected void stopTask() { 3 flag = false; 4 } 5 6 @Override 7 public void run() { 8 while (flag) { 9 // 執行任務... 10 } 11 } View Code

說明:線程中有一個flag標記,它的默認值是true;并且我們提供stopTask()來設置flag標記。當我們需要終止該線程時,調用該線程的stopTask()方法就可以讓線程退出while循環。
注意:將flag定義為volatile類型,是為了保證flag的可見性。即其它線程通過stopTask()修改了flag之后,本線程能看到修改后的flag的值。

綜合線程處于“阻塞狀態”和“運行狀態”的終止方式,比較通用的終止線程的形式如下:

1 @Override 2 public void run() { 3 try { 4 // 1. isInterrupted()保證,只要中斷標記為true就終止線程。 5 while (!isInterrupted()) { 6 // 執行任務... 7 } 8 } catch (InterruptedException ie) { 9 // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止。 10 } 11 } View Code

3. 終止線程的示例

interrupt()常常被用來終止“阻塞狀態”線程。參考下面示例:

1 // Demo1.java的源碼 2 class MyThread extends Thread { 3 4 public MyThread(String name) { 5 super(name); 6 } 7 8 @Override 9 public void run() { 10 try { 11 int i=0; 12 while (!isInterrupted()) { 13 Thread.sleep(100); // 休眠100ms 14 i++; 15 System.out.println(Thread.currentThread().getName()+" ("+this.getState()+") loop " + i); 16 } 17 } catch (InterruptedException e) { 18 System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException."); 19 } 20 } 21 } 22 23 public class Demo1 { 24 25 public static void main(String[] args) { 26 try { 27 Thread t1 = new MyThread("t1"); // 新建“線程t1” 28 System.out.println(t1.getName() +" ("+t1.getState()+") is new."); 29 30 t1.start(); // 啟動“線程t1” 31 System.out.println(t1.getName() +" ("+t1.getState()+") is started."); 32 33 // 主線程休眠300ms,然后主線程給t1發“中斷”指令。 34 Thread.sleep(300); 35 t1.interrupt(); 36 System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted."); 37 38 // 主線程休眠300ms,然后查看t1的狀態。 39 Thread.sleep(300); 40 System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now."); 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 } 45 } View Code

運行結果

t1 (NEW) is new. t1 (RUNNABLE) is started. t1 (RUNNABLE) loop 1 t1 (RUNNABLE) loop 2 t1 (TIMED_WAITING) is interrupted. t1 (RUNNABLE) catch InterruptedException. t1 (TERMINATED) is interrupted now.

結果說明
(01) 主線程main中通過new MyThread("t1")創建線程t1,之后通過t1.start()啟動線程t1。
(02) t1啟動之后,會不斷的檢查它的中斷標記,如果中斷標記為“false”;則休眠100ms。
(03) t1休眠之后,會切換到主線程main;主線程再次運行時,會執行t1.interrupt()中斷線程t1。t1收到中斷指令之后,會將t1的中斷標記設置“false”,而且會拋出InterruptedException異常。在t1的run()方法中,是在循環體while之外捕獲的異常;因此循環被終止。

我們對上面的結果進行小小的修改,將run()方法中捕獲InterruptedException異常的代碼塊移到while循環體內。

1 // Demo2.java的源碼 2 class MyThread extends Thread { 3 4 public MyThread(String name) { 5 super(name); 6 } 7 8 @Override 9 public void run() { 10 int i=0; 11 while (!isInterrupted()) { 12 try { 13 Thread.sleep(100); // 休眠100ms 14 } catch (InterruptedException ie) { 15 System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException."); 16 } 17 i++; 18 System.out.println(Thread.currentThread().getName()+" ("+this.getState()+") loop " + i); 19 } 20 } 21 } 22 23 public class Demo2 { 24 25 public static void main(String[] args) { 26 try { 27 Thread t1 = new MyThread("t1"); // 新建“線程t1” 28 System.out.println(t1.getName() +" ("+t1.getState()+") is new."); 29 30 t1.start(); // 啟動“線程t1” 31 System.out.println(t1.getName() +" ("+t1.getState()+") is started."); 32 33 // 主線程休眠300ms,然后主線程給t1發“中斷”指令。 34 Thread.sleep(300); 35 t1.interrupt(); 36 System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted."); 37 38 // 主線程休眠300ms,然后查看t1的狀態。 39 Thread.sleep(300); 40 System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now."); 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 } 45 } View Code

運行結果

t1 (NEW) is new. t1 (RUNNABLE) is started. t1 (RUNNABLE) loop 1 t1 (RUNNABLE) loop 2 t1 (TIMED_WAITING) is interrupted. t1 (RUNNABLE) catch InterruptedException. t1 (RUNNABLE) loop 3 t1 (RUNNABLE) loop 4 t1 (RUNNABLE) loop 5 t1 (TIMED_WAITING) is interrupted now. t1 (RUNNABLE) loop 6 t1 (RUNNABLE) loop 7 t1 (RUNNABLE) loop 8 t1 (RUNNABLE) loop 9 ...

結果說明
程序進入了死循環!
為什么會這樣呢?這是因為,t1在“等待(阻塞)狀態”時,被interrupt()中斷;此時,會清除中斷標記[即isInterrupted()會返回false],而且會拋出InterruptedException異常[該異常在while循環體內被捕獲]。因此,t1理所當然的會進入死循環了。
解決該問題,需要我們在捕獲異常時,額外的進行退出while循環的處理。例如,在MyThread的catch(InterruptedException)中添加break 或 return就能解決該問題。

下面是通過“額外添加標記”的方式終止“狀態狀態”的線程的示例:

1 // Demo3.java的源碼 2 class MyThread extends Thread { 3 4 private volatile boolean flag= true; 5 public void stopTask() { 6 flag = false; 7 } 8 9 public MyThread(String name) { 10 super(name); 11 } 12 13 @Override 14 public void run() { 15 synchronized(this) { 16 try { 17 int i=0; 18 while (flag) { 19 Thread.sleep(100); // 休眠100ms 20 i++; 21 System.out.println(Thread.currentThread().getName()+" ("+this.getState()+") loop " + i); 22 } 23 } catch (InterruptedException ie) { 24 System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException."); 25 } 26 } 27 } 28 } 29 30 public class Demo3 { 31 32 public static void main(String[] args) { 33 try { 34 MyThread t1 = new MyThread("t1"); // 新建“線程t1” 35 System.out.println(t1.getName() +" ("+t1.getState()+") is new."); 36 37 t1.start(); // 啟動“線程t1” 38 System.out.println(t1.getName() +" ("+t1.getState()+") is started."); 39 40 // 主線程休眠300ms,然后主線程給t1發“中斷”指令。 41 Thread.sleep(300); 42 t1.stopTask(); 43 System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted."); 44 45 // 主線程休眠300ms,然后查看t1的狀態。 46 Thread.sleep(300); 47 System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now."); 48 } catch (InterruptedException e) { 49 e.printStackTrace(); 50 } 51 } 52 } View Code

運行結果

t1 (NEW) is new. t1 (RUNNABLE) is started. t1 (RUNNABLE) loop 1 t1 (RUNNABLE) loop 2 t1 (TIMED_WAITING) is interrupted. t1 (RUNNABLE) loop 3 t1 (TERMINATED) is interrupted now.

4. interrupted() 和 isInterrupted()的區別

最后談談 interrupted() 和 isInterrupted()。
interrupted() 和 isInterrupted()都能夠用于檢測對象的“中斷標記”。
區別是,interrupted()除了返回中斷標記之外,它還會清除中斷標記(即將中斷標記設為false);而isInterrupted()僅僅返回中斷標記。

轉自:http://www.cnblogs.com/skywang12345/p/3479949.html

?

轉載于:https://www.cnblogs.com/yixiu868/p/8142787.html

總結

以上是生活随笔為你收集整理的Java多线程系列--“基础篇”09之 interrupt()和线程终止方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品在线视频一区 | 国产欧美视频在线播放 | 在线国产视频一区 | 欧美在线中文字幕 | 18禁一区二区三区 | 一区二区视频在线观看 | 日本一区二区视频在线播放 | 国产在线无| 国产视频一区二区不卡 | 欧美xxxx黑人又粗又长密月 | 国产精品资源在线 | 特级黄色录像 | 亚洲精品国产综合 | 妞妞av| 爱爱视频免费看 | 欧美成人吸奶水做爰 | 日本黄色性视频 | 日日摸天天添天天添破 | 青草99| 一级黄色在线观看 | 91蜜桃在线 | 91精品国产91综合久久蜜臀 | 国产日韩av在线 | 国产最新精品视频 | 91看片在线观看 | 在线看片不卡 | 美腿丝袜亚洲综合 | 91成人在线观看喷潮动漫 | 国产伦子伦对白视频 | 91色影院 | 美女扒开粉嫩的尿囗给男生桶 | 天天激情综合 | 九九涩| 久久天天躁狠狠躁夜夜躁2014 | 特黄视频在线观看 | 娇喘顶撞深初h1v1 | 狠狠干91| 强伦人妻一区二区三区 | 一级大片免费 | 亚洲午夜精品久久久久久app | 日本二区视频 | 伊人久久久 | 国产夫妻自拍小视频 | 国产99页 | 蜜臀aⅴ国产精品久久久国产老师 | 国产日韩欧美另类 | 中文字幕欧美专区 | 国产精品极品 | 日日夜夜网站 | 亚欧洲精品 | 亚洲色图日韩 | gv天堂gv无码男同在线观看 | 18岁成年人网站 | 欧美激情在线播放 | 日屁网站 | 亚洲国产精品网站 | 乖女从小调教h尿便器小说 欧美韩一区二区 | 香蕉视频在线免费播放 | 亚洲一区二区三区网站 | 夜夜涩 | 狼人伊人久久 | 日本蜜桃视频 | 午夜激情在线观看 | 在线观看www. | 精品国产日本 | 有奶水的迷人少妇 | 日日噜噜噜噜久久久精品毛片 | 精品欧美一区二区久久久 | 国产激情自拍 | 免费看国产片在线观看 | 中文亚洲av片在线观看 | 99re国产精品 | 一个人免费在线观看视频 | 欧美日本久久 | 性做久久久久久免费观看欧美 | 九色自拍视频 | 亚洲精品1区2区 | 尤物视频在线观看免费 | 麻豆免费在线观看 | 久久久青青 | 国产野外作爱视频播放 | 久久九九国产视频 | 亚洲少妇30p | 不卡av在线免费观看 | 日本一区二区在线看 | 欧美做爰猛烈床戏大尺度 | 亚洲精品7777 | 黄色av大全 | 日本福利视频导航 | 四虎免费观看 | www日韩av| 先锋影音一区二区三区 | 激情五月亚洲 | 黄色国产在线 | 老司机深夜福利视频 | 嫩草精品 | 国产精品白嫩极品美女视频 | 谁有毛片网址 | 美女又爽又黄免费 |