摘要:正確方法通過中斷來取消線程。小結調用并不意味著立即停止目標線程正在進行的工作,而只是傳遞了請求中斷的消息。在使用靜態(tài)的時應該小心,因為它會清除當前線程的中斷狀態(tài)。
序
本文展示一個常見的取消線程的方法。
錯誤實例class BrokenPrimeProducer extends Thread { private final BlockingQueuequeue; private volatile boolean cancelled = false; BrokenPrimeProducer(BlockingQueue queue) { this.queue = queue; } public void run() { try { BigInteger p = BigInteger.ONE; while (!cancelled){ queue.put(p = p.nextProbablePrime()); } } catch (InterruptedException consumed) { } } public void cancel() { cancelled = true; } }
正確方法這里試圖用一個標志來跳出while循環(huán),理論上貌似可行,但是這里使用的是阻塞的操作,那么就出現(xiàn)一種場景,線程永遠阻塞在put方法,根本就沒來得及下個循環(huán)去判斷cancelled這個條件,造成永遠無法停止掉線程。
通過中斷來取消線程。
public class PrimeProducer extends Thread { private final BlockingQueuequeue; PrimeProducer(BlockingQueue queue) { this.queue = queue; } public void run() { try { BigInteger p = BigInteger.ONE; while (!Thread.currentThread().isInterrupted()){ queue.put(p = p.nextProbablePrime()); } } catch (InterruptedException consumed) { /* Allow thread to exit */ } } public void cancel() { interrupt(); } }
小結這里的關鍵是queue的put操作能夠響應interrupt方法,拋出InterruptedException,倒不是因為while條件里頭的isInterrupted,這里while條件換成boolean可以照樣可以。
調用interrupt并不意味著立即停止目標線程正在進行的工作,而只是傳遞了請求中斷的消息。對中斷操作的正確理解是:它并不會真正地中斷一個正在運行的線程,而只是發(fā)出中斷請求,然后由線程在下一個合適的時刻中斷自己。
有些方法,例如wait、sleep和join等,將嚴格地處理這種請求,當它們收到中斷請求或者在開始執(zhí)行時發(fā)現(xiàn)某個已被設置好的中斷狀態(tài)時,將拋出一個異常。設計良好的方法可以完全忽略這種請求,只要它們能使調用代碼對中斷請求進行某種處理。
設計糟糕的方法可能會屏蔽中斷請求,從而導致調用棧中的其他代碼無法對中斷請求作出響應。在使用靜態(tài)的interrupted時應該小心,因為它會清除當前線程的中斷狀態(tài)。如果在調用interrupted時返回了true,那么除非你想屏蔽這個中斷,否則必須對它進行處理—可以拋出InterruptedException,或者通過再次調用interrupt來恢復中斷狀態(tài)。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70433.html
摘要:發(fā)布配置支持程序自動發(fā)布配置,創(chuàng)建和修改配置使用同一個方法,配置不存在則創(chuàng)建配置已存在則更新。示例源碼項目代碼已上傳至碼云和上,歡迎下載學習參考資料用戶指南的推薦閱讀系列歡迎來到的世界系列基于的注冊中心系列基于的配置中心 Maven依賴 Nacos提供完整的Java SDK,便于配置管理和服務發(fā)現(xiàn)及管理,以 Nacos-0.8.0 版本為例 添加Maven依賴: com.al...
摘要:程序執(zhí)行時,至少會有一個線程在運行,這個運行的線程被稱為主線程。程序的終止是指除守護線程以外的線程全部終止。多線程程序由多個線程組成的程序稱為多線程程序。線程休眠期間可以被中斷,中斷將會拋出異常。 線程 我們在閱讀程序時,表面看來是在跟蹤程序的處理流程,實際上跟蹤的是線程的執(zhí)行。 單線程程序 在單線程程序中,在某個時間點執(zhí)行的處理只有一個。 Java 程序執(zhí)行時,至少會有一個線程在運行...
摘要:類提供了一些有用的方法在線程池中執(zhí)行內的任務。在線程池提交任務后返回了一個對象,使用它可以知道任務的狀態(tài)和得到返回的執(zhí)行結果。 Callable和Future出現(xiàn)的原因 創(chuàng)建線程的2種方式,一種是直接繼承Thread,另外一種就是實現(xiàn)Runnable接口。 這2種方式都有一個缺陷就是:在執(zhí)行完任務之后無法獲取執(zhí)行結果。 如果需要獲取執(zhí)行結果,就必須通過共享變量或者使用線程通信的方式來達...
摘要:抽象類有一個方法用于使通道處于阻塞模式或非阻塞模式。注意抽象類的方法是由抽象類實現(xiàn)的,都是直接繼承了抽象類。大家有興趣可以看看的源碼,各種抽象類和抽象類上層的抽象類。 歷史回顧: Java NIO 概覽 Java NIO 之 Buffer(緩沖區(qū)) Java NIO 之 Channel(通道) 其他高贊文章: 面試中關于Redis的問題看這篇就夠了 一文輕松搞懂redis集群原理及搭建...
摘要:方法接收的是的實例,但是它沒有返回值方法是函數(shù)式接口,無參數(shù),會返回一個結果這兩個方法是的升級,表示讓任務在指定的線程池中執(zhí)行,不指定的話,通常任務是在線程池中執(zhí)行的。該的接口是在線程使用舊的接口,它不允許返回值。 簡介 作為Java 8 Concurrency API改進而引入,本文是CompletableFuture類的功能和用例的介紹。同時在Java 9 也有對Completab...
閱讀 1958·2021-11-16 11:45
閱讀 3668·2021-09-06 15:02
閱讀 2013·2019-08-30 15:44
閱讀 2283·2019-08-30 11:21
閱讀 1845·2019-08-29 16:31
閱讀 3422·2019-08-29 13:55
閱讀 1895·2019-08-29 12:15
閱讀 3251·2019-08-28 18:05