本篇內(nèi)容介紹了“Java中的線(xiàn)程中斷方法怎么用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)建站于2013年開(kāi)始,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元梁平做網(wǎng)站,已為上家服務(wù),為梁平各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話(huà):18982081108
Java多線(xiàn)程編程中的interrupt()
方法、isInterrupted()
方法和interrupted()
方法都是跟線(xiàn)程中斷相關(guān)的方法,都非常重要。這三個(gè)方法名稱(chēng)非常相似,不理解原理時(shí)容易混淆,這里分別介紹下,以加以區(qū)分。由于interrupt()
方法和isInterrupted()
方法都是實(shí)例方法(非類(lèi)上的靜態(tài)方法),因此我在前面加了個(gè)thread1
,表示一個(gè)實(shí)例化的具體線(xiàn)程:
thread1.interrupt()
方法用來(lái)中斷線(xiàn)程,所謂的中斷,大家可以通俗的理解為打斷
。比如有兩個(gè)線(xiàn)程a
和b
,當(dāng)線(xiàn)程a
因?yàn)槟承┰蛳氪驍嗑€(xiàn)程b
時(shí),a
線(xiàn)程內(nèi)部可以調(diào)用b.interrupt()
。不過(guò)要注意,實(shí)現(xiàn)上是通過(guò)設(shè)置線(xiàn)程b
的中斷狀態(tài)標(biāo)記
實(shí)現(xiàn)的。b
線(xiàn)程代碼運(yùn)行期間,可以在一個(gè)循環(huán)體內(nèi)不斷的判斷該中斷狀態(tài)標(biāo)記
,以確認(rèn)是否真正響應(yīng)a
的中斷請(qǐng)求(比如退出執(zhí)行等等)。
thread1.isInterrupted()
方法用來(lái)獲取一個(gè)線(xiàn)程的中斷狀態(tài)。比如有兩個(gè)線(xiàn)程a
和b
,當(dāng)線(xiàn)程a
因?yàn)槟承┰蛳氪驍嗑€(xiàn)程b
時(shí),可以通過(guò)b.interrupt()
對(duì)b
進(jìn)行中斷。在線(xiàn)程b
內(nèi)部,可以判斷自己的中斷狀態(tài),是否是被中斷的,然后根據(jù)中斷狀態(tài)確認(rèn)是否響應(yīng)中斷請(qǐng)求(比如退出當(dāng)前線(xiàn)程的循環(huán)體等等)。thread1.isInterrupted()
方法內(nèi)部直接調(diào)用了native
方法,傳入的ClearInterrupted
參數(shù)是false
,表示不清空中斷狀態(tài)標(biāo)記:
public boolean isInterrupted() {
return isInterrupted(false);
}// ClearInterrupted表示是否清楚中斷狀態(tài)標(biāo)記private native boolean isInterrupted(boolean ClearInterrupted);
因此調(diào)用完該方法后,中斷標(biāo)志位不清除。
Thread.interrupted()
是定義在Thread
類(lèi)上的靜態(tài)方法,用來(lái)判斷當(dāng)前線(xiàn)程的中斷狀態(tài),跟thread1.isInterrupted()
不同的是,該方法返回中斷狀態(tài)之后,會(huì)復(fù)位(reset)中斷狀態(tài)標(biāo)記,所謂的復(fù)位即恢復(fù)默認(rèn)狀態(tài),也可以說(shuō)是清空中斷狀態(tài)標(biāo)記???code>Thread類(lèi)源碼可以看到Thread.interrupted()
方法實(shí)現(xiàn)非常簡(jiǎn)單,內(nèi)部直接調(diào)用了native
方法,只不過(guò)ClearInterrupted
參數(shù)傳的是true
,表示清空中斷狀態(tài)標(biāo)記:
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}// ClearInterrupted表示是否清楚中斷狀態(tài)標(biāo)記private native boolean isInterrupted(boolean ClearInterrupted);
可以看出thread1.isInterrupted()
和Thread.interrupted()
的區(qū)別其實(shí)就在于獲取完中斷狀態(tài)標(biāo)記之后,是否復(fù)位。大家可以根據(jù)需要進(jìn)行選擇使用。
要想優(yōu)雅的停止某個(gè)線(xiàn)程的運(yùn)行,需要前面介紹的中斷機(jī)制。比如兩個(gè)線(xiàn)程a
和b
,當(dāng)線(xiàn)程a
想中斷線(xiàn)程b
時(shí),可以通過(guò)調(diào)用b.interrupt()
方法,來(lái)設(shè)置線(xiàn)程b
的中斷標(biāo)記,以達(dá)到通知線(xiàn)程b
的目的。而線(xiàn)程b
需要不斷的檢查自己的中斷標(biāo)記,以隨時(shí)響應(yīng)其他線(xiàn)程的中斷,比如下面的實(shí)現(xiàn)所示:
public class TestMain {
public static void main(String[] args) throws InterruptedException {
Thread b = new Thread(new Runnable() {
@Override
public void run() {
int num = 0;
while(true) {
if (Thread.interrupted()) {
break;
}
System.out.println("thread b running, num is:" + num++);
}
}
});
b.start();
// 主線(xiàn)程sleep 1ms,讓線(xiàn)程b循環(huán)一小會(huì)
Thread.sleep(1);
// 中斷線(xiàn)程b
b.interrupt();
}
}
這里在主線(xiàn)程
內(nèi)新創(chuàng)建了一個(gè)線(xiàn)程b
,線(xiàn)程b
內(nèi)部是一個(gè)循環(huán)體,每次循環(huán)開(kāi)始都檢查一下中斷狀態(tài),確認(rèn)是否被中斷,如果被中斷了即退出循環(huán),結(jié)束線(xiàn)程的執(zhí)行。主線(xiàn)程sleep了1ms,讓線(xiàn)程b先循環(huán)幾次。接著主線(xiàn)程通過(guò)b.interrupt()
對(duì)線(xiàn)程b
進(jìn)行中斷。運(yùn)行程序可以看到輸出如下(不同機(jī)器運(yùn)行結(jié)果不一樣):
thread b running, num is:0thread b running, num is:1thread b running, num is:2...
thread b running, num is:25thread b running, num is:26thread b running, num is:27Process finished with exit code 0
可以看到主線(xiàn)程成功的中斷了線(xiàn)程b
。當(dāng)然,主線(xiàn)程之所以能成功的中斷線(xiàn)程b
,是因?yàn)榫€(xiàn)程b
一直在檢查自己的中斷狀態(tài)(如果線(xiàn)程b
太自我,不考慮其他線(xiàn)程,只考慮自己運(yùn)行,那主線(xiàn)程就無(wú)法成功打斷線(xiàn)程b
了)。
前面我們成功的在主線(xiàn)程中中斷了線(xiàn)程b
,然后如果線(xiàn)程b
中存在阻塞,比如下面的代碼所示,線(xiàn)程b
在sleep時(shí)被主線(xiàn)程中斷:
public class TestMain {
public static void main(String[] args) throws InterruptedException {
Thread b = new Thread(new Runnable() {
@Override
public void run() {
int num = 0;
while(true) {
if (Thread.interrupted()) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Thread.currentThread().interrupt();
e.printStackTrace();
}
System.out.println("thread b running, num is:" + num++);
}
}
});
b.start();
// 主線(xiàn)程sleep5.5秒,讓線(xiàn)程b循環(huán)5次
Thread.sleep(5500);
// 中斷線(xiàn)程b
b.interrupt();
}
}
這時(shí)線(xiàn)程b
會(huì)拋出InterruptedException
異常,上面的代碼中我們僅僅打印了下該異常,相當(dāng)于什么都沒(méi)做。運(yùn)行該代碼結(jié)果如下:
thread b running, num is:0thread b running, num is:1thread b running, num is:2thread b running, num is:3thread b running, num is:4java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.TestMain$1.run(TestMain.java:25)
at java.lang.Thread.run(Thread.java:748)
thread b running, num is:5thread b running, num is:6thread b running, num is:7thread b running, num is:8thread b running, num is:9...
可以看出,主線(xiàn)程未能成功中斷線(xiàn)程b
。
線(xiàn)程內(nèi)調(diào)用wait
,join
,sleep
時(shí)都會(huì)進(jìn)入阻塞狀態(tài)。當(dāng)線(xiàn)程處于阻塞狀態(tài)時(shí)被中斷,這時(shí)線(xiàn)程就會(huì)拋出InterruptedException
異常,其實(shí)大家可以通俗的理解為一種通知即可。以sleep
方法為例,大家可以按如下模擬實(shí)現(xiàn)來(lái)理解(底層是native實(shí)現(xiàn)):
public static void sleep(long millis) throws InterruptedException
{
while (/* still waiting for millis to become zero */)
{
if (Thread.interrupted())
{
throw new InterruptedException();
}
// Keep waiting
}
}
有了InterruptedException
異常通知,線(xiàn)程就可以在阻塞時(shí)立即知道被中斷了,進(jìn)而采取一定的措施響應(yīng)中斷。需要注意的一點(diǎn)是,由于拋出了InterruptedException
異常,因此不會(huì)在設(shè)置中斷標(biāo)志位。
理解了InterruptedException
異常,我們就可以在線(xiàn)程即使發(fā)生阻塞時(shí)也能成功進(jìn)行中斷了,如下所示:
public class TestMain {
public static void main(String[] args) throws InterruptedException {
Thread b = new Thread(new Runnable() {
@Override
public void run() {
int num = 0;
while(true) {
if (Thread.interrupted()) {
break;
}
try {
Thread.sleep(1000); // 用sleep來(lái)模擬線(xiàn)程的執(zhí)行
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 注意這里是重點(diǎn)!
}
System.out.println("thread b running, num is:" + num++);
}
}
});
b.start();
// 主線(xiàn)程sleep5.5秒,讓線(xiàn)程b先循環(huán)5次
Thread.sleep(5500);
// 中斷線(xiàn)程b
b.interrupt();
}
}
這里我們?cè)跈z查到InterruptedException
異常時(shí),重新設(shè)置了中斷標(biāo)志位,這樣下次循環(huán)一開(kāi)始時(shí),即可判斷被中斷了,進(jìn)而退出循環(huán)體。當(dāng)然我們可以在InterruptedException
異常catch
時(shí)直接退出。
“Java中的線(xiàn)程中斷方法怎么用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
當(dāng)前名稱(chēng):Java中的線(xiàn)程中斷方法怎么用
轉(zhuǎn)載源于:http://bm7419.com/article4/jcspie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站營(yíng)銷(xiāo)、網(wǎng)站設(shè)計(jì)公司、、搜索引擎優(yōu)化、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
移動(dòng)網(wǎng)站建設(shè)知識(shí)