日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

深入分析JAVA 多線程--interrupt()和線程終止方式

瀏覽:62日期:2022-08-30 15:14:10

一、interrupt() 介紹

interrupt() 定義在 Thread 類中,作用是中斷本線程。

本線程中斷自己是被允許的;其它線程調用本線程的 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。中斷一個“已終止的線程”不會產生任何操作。

二、線程終止方式

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

(一)、終止處于“阻塞狀態”的線程.

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

public void run() { try { while (true) { // 執行業務 } } catch (InterruptedException ie) { // 由于產生InterruptedException異常,退出while(true)循環,線程終止! }}

說明:

在while(true)中不斷的執行業務代碼,當線程處于阻塞狀態時,調用線程的 interrupt() 產生 InterruptedException 中斷。中斷的捕獲在 while(true) 之外,這樣就退出了 while(true) 循環!

注意:

對 InterruptedException 的捕獲務一般放在 while(true) 循環體的外面,這樣,在產生異常時就退出了 while(true) 循環。否則,InterruptedException 在 while(true) 循環體之內,就需要額外的添加退出處理。形式如下:

public void run() { while (true) { try { // 執行任務... } catch (InterruptedException ie) { // InterruptedException在while(true)循環體內。 // 當線程產生了InterruptedException異常時,while(true)仍能繼續運行!需要手動退出 break; } }}

說明:

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

(二)、終止處于“運行狀態”的線程

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

1、通過“中斷標記”終止線程

public void run() { while (!isInterrupted()) { // 執行任務... }}

說明:

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

注意:interrupt() 并不會終止處于“運行狀態”的線程!它會將線程的中斷標記設為 true。

2、通過“額外添加標記”終止線程

private volatile boolean flag= true;protected void stopTask() { flag = false;}public void run() { while (flag) { // 執行任務... }}

說明:

線程中有一個 flag 標記,它的默認值是 true;并且我們提供 stopTask() 來設置 flag 標記。當我們需要終止該線程時,調用該線程的 stopTask() 方法就可以讓線程退出 while 循環。

注意:將 flag 定義為 volatile 類型,是為了保證 flag 的可見性。即其它線程通過 stopTask() 修改了 flag 之后,本線程能看到修改后的 flag 的值。

(三)、通過方式

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

public void run() { try { // 1. isInterrupted()保證,只要中斷標記為true就終止線程。 while (!isInterrupted()) { // 執行任務... } } catch (InterruptedException ie) { // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止。 }}

1、isInterrupted()保證,只要中斷標記為 true 就終止線程。2、InterruptedException 異常保證,當 InterruptedException 異常產生時,線程被終止。

三、示例

public class InterruptTest { public static void main(String[] args) { try { Thread t1 = new MyThread('t1'); // 新建線程t1 System.out.println(t1.getName() + '[' + t1.getState() + '] is new.'); t1.start();// 啟動線程t1 System.out.println(t1.getName() + '[' + t1.getState() + '] is started.'); Thread.sleep(300);// 休眠300毫秒,然后主線程給t1發“中斷”指令,查看t1狀態 t1.interrupt(); System.out.println(t1.getName() + '[' + t1.getState() + '] is interrupted.'); Thread.sleep(300);// 休眠300毫秒,然后查看t1狀態 System.out.println(t1.getName() + '[' + t1.getState() + '] is interrupted now.'); }catch(InterruptedException e) { e.printStackTrace(); } }}class MyThread extends Thread{ public MyThread(String name) { super(name); } @Override public void run() { try { int i = 0; while(!isInterrupted()) {Thread.sleep(100);// 休眠100毫秒++i;System.out.println(Thread.currentThread().getName() + '[' + this.getState() + '] loop ' + i); } }catch(InterruptedException e) { System.out.println(Thread.currentThread().getName() + '[' + this.getState() + '] catch InterruptedException'); } }}

運行結果

t1 [ NEW ] is new.t1 [ RUNNABLE ] is started.t1 [ RUNNABLE ] loop 1t1 [ RUNNABLE ] loop 2t1 [ RUNNABLE ] loop 3t1 [ RUNNABLE ] catch InterruptedExceptiont1 [ TERMINATED ] is interrupted.t1 [ TERMINATED ] is interrupted now.

說明:

①、主線程 main 中通過 new MyThread('t1') 創建線程 t1,之后通過 t1.start() 啟動線程 t1。

②、t1 啟動之后,會不斷的檢查它的中斷標記,如果中斷標記為“false”;則休眠 100ms。

③、t1 休眠之后,會切換到主線程main;主線程再次運行時,會執行t1.interrupt()中斷線程t1。t1收到中斷指令之后,會將t1的中斷標記設置“false”,而且會拋出 InterruptedException 異常。在 t1 的 run() 方法中,是在循環體 while 之外捕獲的異常;因此循環被終止。

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

public class InterruptTest { public static void main(String[] args) { try { Thread t1 = new MyThread('t1'); // 新建線程t1 System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is new.'); t1.start();// 啟動線程t1 System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is started.'); Thread.sleep(300);// 休眠300毫秒,然后主線程給t1發“中斷”指令,查看t1狀態 t1.interrupt(); System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is interrupted.'); Thread.sleep(300);// 休眠300毫秒,然后查看t1狀態 System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is interrupted now.'); }catch(InterruptedException e) { e.printStackTrace(); } }}class MyThread extends Thread{ public MyThread(String name) { super(name); } @Override public void run() { int i = 0; while(!isInterrupted()) { try {Thread.sleep(100); // 休眠100ms } catch (InterruptedException ie) { System.out.println(Thread.currentThread().getName() +' [ '+this.getState()+' ] catch InterruptedException.'); } i++; System.out.println(Thread.currentThread().getName()+' [ '+this.getState()+' ] loop ' + i); } }}

運行結果

t1 [ NEW ] is new.t1 [ RUNNABLE ] is started.t1 [ RUNNABLE ] loop 1t1 [ RUNNABLE ] loop 2t1 [ TIMED_WAITING ] is interrupted.t1 [ RUNNABLE ] catch InterruptedException.t1 [ RUNNABLE ] loop 3t1 [ RUNNABLE ] loop 4t1 [ RUNNABLE ] loop 5t1 [ RUNNABLE ] loop 6t1 [ RUNNABLE ] is interrupted now.t1 [ RUNNABLE ] loop 7...... // 無限循環

說明:

程序進入了死循環了。

這是因為,t1在“等待(阻塞)狀態”時,被 interrupt() 中斷;此時,會清除中斷標記(即 isInterrupted() 會返回 false),而且會拋出 InterruptedException 異常(該異常在while循環體內被捕獲)。因此,t1理所當然的會進入死循環了。

解決該問題,需要我們在捕獲異常時,額外的進行退出 while 循環的處理。例如,在 MyThread 的 catch(InterruptedException) 中添加 break 或 return 就能解決該問題。

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

public class InterruptTest { public static void main(String[] args) { try { MyThread t1 = new MyThread('t1'); // 新建線程t1 System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is new.'); t1.start();// 啟動線程t1 System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is started.'); Thread.sleep(300);// 休眠300毫秒,然后主線程給t1發“中斷”指令,查看t1狀態 t1.stopTask(); System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is interrupted.'); Thread.sleep(300);// 休眠300毫秒,然后查看t1狀態 System.out.println(t1.getName() + ' [ ' + t1.getState() + ' ] is interrupted now.'); }catch(InterruptedException e) { e.printStackTrace(); } }}class MyThread extends Thread{ private volatile boolean flag = true; public void stopTask() { flag = false; } public MyThread(String name) { super(name); } @Override public void run() { synchronized (this) { int i = 0; while(flag) {try { Thread.sleep(100); // 休眠100ms} catch (InterruptedException ie) { System.out.println(Thread.currentThread().getName() +' [ '+this.getState()+' ] catch InterruptedException.'); break;}i++;System.out.println(Thread.currentThread().getName()+' [ '+this.getState()+' ] loop ' + i); } } }}

運行結果

t1 [ NEW ] is new.t1 [ RUNNABLE ] is started.t1 [ RUNNABLE ] loop 1t1 [ RUNNABLE ] loop 2t1 [ RUNNABLE ] loop 3t1 [ RUNNABLE ] is interrupted.t1 [ TERMINATED ] is interrupted now.

四、interrupted() 和 isInterrupted()的區別

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

以上就是深入分析JAVA 多線程--interrupt()和線程終止方式的詳細內容,更多關于JAVA 多線程--interrupt()和線程終止的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99视频精品全国免费| 日韩二区在线观看| 久久精品欧洲| 久久99蜜桃| 精品一区二区男人吃奶| 欧美成人精品一级| 国产成人精品亚洲线观看| 四虎8848精品成人免费网站| av中文字幕在线观看第一页| 久久不卡国产精品一区二区| 在线观看精品| 欧美中文日韩| 老司机精品视频在线播放| 欧美日韩一二| 日本va欧美va欧美va精品| 伊人久久av| 亚洲精品激情| 日韩成人三级| 日韩不卡一区二区三区| 国产 日韩 欧美一区| 亚洲精品四区| 欧美13videosex性极品| 免费在线观看成人| 国产91欧美| 亚洲精品1区| 麻豆精品在线播放| 香蕉成人久久| 成人一区不卡| 日本中文字幕不卡| 久久久久久久久久久妇女| 日韩区一区二| 国产尤物精品| 久久影视三级福利片| 亚洲免费观看| 国产精品久久久久久久久妇女| 蜜臀精品久久久久久蜜臀| 日韩成人精品一区二区| 日韩高清在线不卡| 欧美高清一区| 国产福利亚洲| 亚洲性视频在线| 91精品在线观看国产| 国产精品1区在线| 久热精品在线| 成人羞羞在线观看网站| 久久国产精品免费精品3p| 91精品二区| 日韩成人高清| 精品三级在线观看视频| 婷婷精品久久久久久久久久不卡| 日韩电影在线视频| 91精品丝袜国产高跟在线| 午夜久久影院| 欧美二三四区| 国产精品视频一区二区三区| 亚洲欧洲一区| 久久久久亚洲| 精品一级视频| 国产九九精品| 亚洲精品成人一区| 亚洲欧美日韩高清在线| 国产粉嫩在线观看| 久久狠狠亚洲综合| 亚洲午夜国产成人| 午夜欧美在线| 久久精选视频| 国产suv精品一区| 国产精品久久久久久久久久齐齐 | 国产精品亚洲人成在99www| 蜜臀久久久久久久| 婷婷激情久久| 亚洲成人va| 高清不卡亚洲| 久久久久免费| 成人精品动漫一区二区三区| 国产激情久久| 国产美女视频一区二区| 青草综合视频| 日韩美女精品| 亚洲一区黄色| 日韩视频久久| 国产亚洲综合精品| 午夜精品亚洲| 亚洲深夜福利| 国产精品普通话对白| 亚洲精品123区| 一区二区自拍| 国产精品日本| 久久先锋影音| 中文不卡在线| 日韩欧美三区| 亚洲97av| 日本成人在线不卡视频| 亚洲精品观看| 亚洲一二av| 日本视频在线一区| 国产一区 二区| 国产精品xxx| 精品黄色一级片| 国产66精品| 一区二区三区四区日本视频| 免费观看亚洲| 香蕉久久精品| 老牛影视一区二区三区| 亚洲精选91| 欧美一区自拍| 卡一卡二国产精品| 亚洲黄色免费看| 久久一区二区三区喷水| 99久久99久久精品国产片果冰 | 天堂久久av| 国产精品白丝久久av网站| 国产成人免费精品| 四虎4545www国产精品 | 精品高清久久| 国产精品毛片久久| 色婷婷精品视频| 日韩午夜黄色| 日韩和欧美一区二区三区| 日本午夜精品久久久久| 久久久久伊人| 国产 日韩 欧美一区| 国产精品色网| 国产乱人伦精品一区| bbw在线视频| 欧美日韩第一| 日韩亚洲精品在线观看| 国产精品va| 国产99亚洲| 亚洲香蕉视频| 国产精品成人一区二区网站软件| av高清不卡| 亚洲在线观看| 国产精品高清一区二区| 奇米色欧美一区二区三区| 国产精品一区亚洲| 国产在线不卡一区二区三区| 黄色aa久久| 美女久久久久| 亚洲精一区二区三区| 欧美激情视频一区二区三区免费| 另类专区亚洲| 免费精品视频在线| 久久亚州av| av成人国产| 日本一不卡视频| 92国产精品| 日韩精品中文字幕一区二区| 狠狠久久伊人中文字幕| 国产日韩专区| 精品中文在线| 国产精品腿扒开做爽爽爽挤奶网站| 久久国产三级| 欧美日韩四区| 国产精品久久| 国产毛片一区| 国产精品国产一区| 视频一区视频二区中文| 国产不卡一区| 亚洲免费一区三区| 国产精品国产一区| 蜜桃视频免费观看一区| 国产精品黑丝在线播放| 中文字幕av一区二区三区人| 国产aa精品| 午夜久久av| 91精品国产乱码久久久久久久| 欧美日韩视频免费看| 亚州av乱码久久精品蜜桃| 欧美a在线观看| 亚洲精品视频一二三区| 久久久天天操| 国产精品v亚洲精品v日韩精品| 亚洲精品午夜av福利久久蜜桃| 欧美激情亚洲| 蜜臀av一区二区三区| 午夜av成人| 国产精品成人自拍| 免费在线成人网| 99精品视频精品精品视频| 国产精品任我爽爆在线播放| 国产精品日韩| 亚洲播播91| 久久精品九色| 日本午夜免费一区二区| 亚洲中午字幕| 亚洲大片在线| 日韩电影免费网址| 麻豆精品视频在线观看免费| 最新国产精品久久久| 在线视频观看日韩| 四虎成人av| 美女久久久精品| 欧美天堂一区| 日本不卡一区二区| 老司机精品久久| 午夜国产一区二区| 国产成人精品亚洲日本在线观看| 国产欧美一区二区三区国产幕精品| 国产视频一区三区|