Java中的線(xiàn)程中斷方法怎么用

本篇內(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)程中斷

1 線(xiàn)程中斷相關(guān)方法介紹

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()方法

thread1.interrupt()方法用來(lái)中斷線(xiàn)程,所謂的中斷,大家可以通俗的理解為打斷。比如有兩個(gè)線(xiàn)程ab,當(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()方法

thread1.isInterrupted()方法用來(lái)獲取一個(gè)線(xiàn)程的中斷狀態(tài)。比如有兩個(gè)線(xiàn)程ab,當(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.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)行選擇使用。

2 不考慮線(xiàn)程阻塞時(shí)如何優(yōu)雅的停止一個(gè)線(xiàn)程

要想優(yōu)雅的停止某個(gè)線(xiàn)程的運(yùn)行,需要前面介紹的中斷機(jī)制。比如兩個(gè)線(xiàn)程ab,當(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了)。

3 考慮線(xiàn)程阻塞時(shí)如何優(yōu)雅的停止一個(gè)線(xiàn)程

前面我們成功的在主線(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。

3.1 InterruptedException異常介紹

線(xiàn)程內(nèi)調(diào)用waitjoin,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)志位。

3.2 考慮線(xiàn)程阻塞時(shí)如何優(yōu)雅的停止一個(gè)線(xiàn)程

理解了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)

綿陽(yáng)服務(wù)器托管