Java線程中的interrupt方法解讀
interrupt方法
首先梳理Thread關于interrupt的定義
/** * Interrupts this thread. * * <p> Unless the current thread is interrupting itself, which is * always permitted, the {@link #checkAccess() checkAccess} method * of this thread is invoked, which may cause a {@link * SecurityException} to be thrown. * * <p> If this thread is blocked in an invocation of the {@link * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link * Object#wait(long, int) wait(long, int)} methods of the {@link Object} * class, or of the {@link #join()}, {@link #join(long)}, {@link * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, * methods of this class, then its interrupt status will be cleared and it * will receive an {@link InterruptedException}. * * <p> If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel InterruptibleChannel} * then the channel will be closed, the thread's interrupt * status will be set, and the thread will receive a {@link * java.nio.channels.ClosedByInterruptException}. * * <p> If this thread is blocked in a {@link java.nio.channels.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 {@link * java.nio.channels.Selector#wakeup wakeup} method were invoked. * * <p> If none of the previous conditions hold then this thread's interrupt * status will be set. </p> * * <p> Interrupting a thread that is not alive need not have any effect. * * @throws SecurityException * if the current thread cannot modify this thread * * @revised 6.0 * @spec JSR-51 */ public void interrupt()
這里講述了Thread實例對象調(diào)用方法interrupt,有這幾種情況
? 1.在線程里面有wait,sleep,join方法,會彈出InterruptedException,狀態(tài)會被清除
? 2.io里面,會彈出異常,狀態(tài)會被設置,…
? 3.如果線程阻塞在nio中的Selector中,狀態(tài)會被設置,…
? 4.如果不是上面,這些情況,狀態(tài)會被設置
可以看出interrupt是關于狀態(tài)的設置
我們來驗證一下
第一種,沒有任何情況的
public static void main(String[] args) { Thread t1 = new Thread(()->{ while(true){ if (interrupted()) { break; } System.out.println("i" + new Date()); } }); t1.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t1.interrupt(); }
線程會在(1000+)ms后結束,整個程序也會結束
第二種,有sleep的情況下
public static void main(String[] args) { Thread t1 = new Thread(()->{ while(true){ if (interrupted()) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("i" + new Date()); } }); t1.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t1.interrupt(); }
方法并不會退出,只是打出了一個InterruptException
如何處理中斷?
- 上文都在介紹如何獲取中斷狀態(tài),那么當我們捕獲到中斷狀態(tài)后,究竟如何處理呢?
- Java類庫中提供的一些可能會發(fā)生阻塞的方法都會拋InterruptedException異常,如:BlockingQueue#put、BlockingQueue#take、Object#wait、Thread#sleep。
- 當你在某一條線程中調(diào)用這些方法時,這個方法可能會被阻塞很長時間,你可以在別的線程中調(diào)用當前線程對象的interrupt方法觸發(fā)這些函數(shù)拋出InterruptedException異常。
- 當一個函數(shù)拋出InterruptedException異常時,表示這個方法阻塞的時間太久了,別人不想等它執(zhí)行結束了。
- 當你的捕獲到一個InterruptedException異常后,亦可以處理它,或者向上拋出。
- 拋出時要注意???:當你捕獲到InterruptedException異常后,當前線程的中斷狀態(tài)已經(jīng)被修改為false(表示線程未被中斷);此時你若能夠處理中斷,則不用理會該值;但如果你繼續(xù)向上拋InterruptedException異常,你需要再次調(diào)用interrupt方法,將當前線程的中斷狀態(tài)設為true。
- 注意:絕對不能“吞掉中斷”!即捕獲了InterruptedException而不作任何處理。這樣違背了中斷機制的規(guī)則,別人想讓你線程中斷,然而你自己不處理,也不將中斷請求告訴調(diào)用者,調(diào)用者一直以為沒有中斷請求。
更新相關interrupt方法的意義
public void interrupt()
Thread里面的打斷函數(shù),可以使用新建一個Thread對象,執(zhí)行thread.interrupt();
修改調(diào)用線程的interrupt 的status
public static boolean interrupted()
該方法可以判斷是否被打斷,但是這個interrupt的status會被清除,
/** * Tests whether the current thread has been interrupted. The * <i>interrupted status</i> of the thread is cleared by this method. In * other words, if this method were to be called twice in succession, the * second call would return false (unless the current thread were * interrupted again, after the first call had cleared its interrupted * status and before the second call had examined it). * * <p>A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return <code>true</code> if the current thread has been interrupted; * <code>false</code> otherwise. * @see #isInterrupted() * @revised 6.0 */
public boolean isInterrupted()
該方法可以判斷是否被打斷
到此這篇關于Java線程中的interrupt方法解讀的文章就介紹到這了,更多相關interrupt方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中List轉(zhuǎn)Map的幾種常見方式與對比
JavaList轉(zhuǎn)Map是一個非常常用的技術,對于Java開發(fā)人員來講,掌握該技術可以幫助我們更加高效地操作List集合中的對象,這篇文章主要給大家介紹了關于Java中List轉(zhuǎn)Map的幾種常見方式與對比的相關資料,需要的朋友可以參考下2024-02-02Spring?Boot?Admin?添加報警提醒和登錄驗證功能的具體實現(xiàn)
報警提醒功能是基于郵箱實現(xiàn)的,當然也可以使用其他的提醒功能,如釘釘或飛書機器人提醒也是可以的,但郵箱報警功能的實現(xiàn)成本最低,所以本文我們就來看郵箱的報警提醒功能的具體實現(xiàn)2022-01-01java datetime數(shù)據(jù)類型去掉時分秒的案例詳解
在Java中,如果我們想要表示一個日期而不包括時間(時分秒),我們通常會使用java.time包中的LocalDate類,這篇文章主要介紹了java datetime數(shù)據(jù)類型去掉時分秒,需要的朋友可以參考下2024-06-06使用RestTemplate調(diào)用https接口跳過證書驗證
這篇文章主要介紹了使用RestTemplate調(diào)用https接口跳過證書驗證,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Spring boot整合Mybatis實現(xiàn)級聯(lián)一對多CRUD操作的完整步驟
這篇文章主要給大家介紹了關于Spring boot整合Mybatis實現(xiàn)級聯(lián)一對多CRUD操作的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-07-07java如何防止表單重復提交的注解@RepeatSubmit
@RepeatSubmit是一個自定義注解,用于防止表單重復提交,它通過AOP和攔截器模式實現(xiàn),結合了線程安全和分布式環(huán)境的考慮,注解參數(shù)包括interval(間隔時間)和message(提示信息),使用時需要注意并發(fā)處理、用戶體驗、性能和安全性等方面,失效原因是多方面的2024-11-11java多線程并發(fā)中使用Lockers類將多線程共享資源鎖定
Lockers在多線程編程里面一個重要的概念是鎖定,如果一個資源是多個線程共享的,為了保證數(shù)據(jù)的完整性,在進行事務性操作時需要將共享資源鎖定,這樣可以保證在做事務性操作時只有一個線程能對資源進行操作,下面看一個示例2014-01-01