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