最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的interrupted()和isInterrupted()

 更新時(shí)間:2021年11月25日 10:40:40   作者:李子捌  
這篇文章主要介紹了Java中的interrupted()和isInterrupted()摸下面文章圍繞interrupted()和isInterrupted()的相關(guān)資料展開詳細(xì)內(nèi)容,需要的小伙伴樂意參考下面下面文章具體價(jià)紹,希望對(duì)大家有所幫助

1、前言

當(dāng)提及如何終止一個(gè)線程時(shí),部分讀者通常立馬想到的方法肯定是stop(),但是stop()方法并不被推薦使用(很多規(guī)范中是禁止使用的),其原因是強(qiáng)制終止一個(gè)線程,會(huì)導(dǎo)致程序不正常的結(jié)束,會(huì)出現(xiàn)資源未正確釋放、程序結(jié)果不正確等等問題。而是否終止一個(gè)線程應(yīng)該把這個(gè)控制權(quán)轉(zhuǎn)交給當(dāng)前被終止的線程本身,此時(shí)采用的辦法就是 ****interrupt()方法來終止,該方法相當(dāng)于修改一個(gè)共享變量的值,當(dāng)運(yùn)行中的線程判斷當(dāng)前值為false則繼續(xù)運(yùn)行,如果有地方調(diào)用當(dāng)前threadinterrupt()方法,那么這個(gè)值將變?yōu)?code>true,此時(shí)當(dāng)前線程可以根據(jù)這個(gè)值的修改來正確的終止線程的運(yùn)行。

2、API

java.lang.Thread中主要提供了如下與線程中斷相關(guān)的方法,其具體方法名與主要作用如下表所示。

方法名 方法作用
public void?interrupt() 中斷此線程
public static boolean?interrupted() 測(cè)試當(dāng)前線程是否被中斷,該方法會(huì)恢復(fù)(清除)中斷標(biāo)志
public boolean?isInterrupted() 測(cè)試當(dāng)前線程是否被中斷,該方法只會(huì)獲取中斷標(biāo)志,不會(huì)恢復(fù)(清除)中斷標(biāo)志
private native boolean?isInterrupted(boolean?ClearInterrupted); interrupted()和isInterrupted()最終調(diào)用,該方法是native本地方法,在jvm中具體實(shí)現(xiàn),也是獲取線程中斷標(biāo)志真正調(diào)用的方法,參數(shù)ClearInterrupted意思是是否恢復(fù)(清除)中斷標(biāo)志

源碼:

/**

 * 中斷此線程

 */

public void interrupt() {

    if (this != Thread.currentThread())

        checkAccess();



    synchronized (blockerLock) {

        Interruptible b = blocker;

        if (b != null) {

            interrupt0();           // Just to set the interrupt flag

            b.interrupt(this);

            return;

        }

    }

    interrupt0();

}



/**

 *	測(cè)試當(dāng)前線程是否被中斷,返回中斷標(biāo)志

 */

public static boolean interrupted() {

    return currentThread().isInterrupted(true);

}



/**

 *	測(cè)試當(dāng)前線程是否被中斷,返回中斷標(biāo)志

 */

public boolean isInterrupted() {

    return isInterrupted(false);

}



/**

 * 線程是否被中斷native方法,ClearInterrupted為是否清除中斷標(biāo)志參數(shù)

 */

private native boolean isInterrupted(boolean ClearInterrupted);



/**

 *	中斷當(dāng)前線程的native方法

 */

private native void interrupt0();

3、interrupted()和isInterrupted()區(qū)別

看了上述API講述和Thread中的源碼,已經(jīng)清楚interrupted()isInterrupted()的主要區(qū)別了

interrupted()為靜態(tài)方法,isInterrupted()為普通方法

interrupted() 返回中斷標(biāo)志且清除(恢復(fù))中斷標(biāo)志,isInterrupted()僅返回中斷標(biāo)志

3.1 使用方法

我們先驗(yàn)證中斷異常響應(yīng),通過如下兩種方法的使用示例來介紹,注意Runner中的run方法的部分區(qū)別

方法一

package com.liziba.p7;

import java.util.concurrent.TimeUnit;

/**

 * <p>

 *      

 * </p>

 *

 * @Author: Liziba

 * @Date: 2021/6/24 21:05

 */

public class ThreadInterruptedDemo { 

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runner(), "Thread-01");

        t1.start();

        // 主線程睡眠1秒,保證t1的充分執(zhí)行

        TimeUnit.SECONDS.sleep(1);

        // 發(fā)起中斷

        t1.interrupt();

    }



    static class Runner implements Runnable {



        @Override

        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                System.out.println(Thread.currentThread().getName() + " is running .");

            }

        }

    }



}

輸出結(jié)果:

可以看到線程在執(zhí)行數(shù)次后終止運(yùn)行

方法二

package com.liziba.p7;

import java.util.concurrent.TimeUnit;



/**

 * <p>

 *

 * </p>

 *

 * @Author: Liziba

 * @Date: 2021/6/24 21:18

 */

public class ThreadInterruptedDemo {



    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runner(), "Thread-01");

        t1.start();

        // 主線程睡眠2秒,保證t1的充分執(zhí)行

        TimeUnit.SECONDS.sleep(1);

        // 發(fā)起中斷

        t1.interrupt();

    }

    static class Runner implements Runnable {



        @Override

        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                System.out.println(Thread.currentThread().getName() + " is running .");

                try {

                    // 睡眠2秒,保證主線程發(fā)起的中斷能被捕獲

                    TimeUnit.SECONDS.sleep(2);

                } catch (InterruptedException e) {

                    // 不對(duì)中斷做任何處理,try住異常,打印

                    e.printStackTrace();

                }

            }

        }

    }



}

輸出結(jié)果:

可以看到main線程中發(fā)起的t1線程中斷,被捕獲住異常后,未做任何處理,線程繼續(xù)持續(xù)不斷的運(yùn)行

總結(jié)上述兩種方式:

方法一和方法二,均通過判斷Thread.currentThread().isInterrupted()的值來運(yùn)行run方法中的邏輯,Thread.currentThread().isInterrupted()在線程未中斷時(shí)返回false,當(dāng)main線程中執(zhí)行 t1.interrupt()時(shí),線程t1被中斷,Thread.currentThread().isInterrupted()的值變?yōu)?code>false;在方法一中,獲取到這個(gè)變化后直接結(jié)束運(yùn)行;在方法二中,由于sleep()使得線程阻塞會(huì)響應(yīng)中斷,但是此時(shí)我僅僅catch住異常,并沒有對(duì)中斷做任何處理,這里有個(gè)知識(shí)點(diǎn)是,線程響應(yīng)中斷拋出異常時(shí),會(huì)恢復(fù)(清除)中斷標(biāo)志,所以t1.interrupt()對(duì)中斷標(biāo)志的修改又被恢復(fù)了,程序仍然不斷的運(yùn)行。

接下來我們來驗(yàn)證interrupted()對(duì)于中斷的標(biāo)志的清除

package com.liziba.p7;



import java.util.concurrent.TimeUnit;



/**

 * <p>

 *		isInterrupted()

 * </p>

 *

 * @Author: Liziba

 * @Date: 2021/6/24 21:20

 */

public class ThreadInterruptDemo2 {



    public static void main(String[] args) throws InterruptedException {



        Thread thread = new Thread(new Runner(), "Thread-1");

        thread.start();

        TimeUnit.SECONDS.sleep(2);

        thread.interrupt();

    }

    static class Runner implements Runnable {



        @Override

        public void run() {

            System.out.println(Thread.currentThread().getName() +" interrupted flag is " + Thread.currentThread().isInterrupted());



            while (!Thread.currentThread().isInterrupted()) {

                try {

                    System.out.println(Thread.currentThread().getName() + " is running .");

                    TimeUnit.SECONDS.sleep(1);

                } catch (InterruptedException e) {

                    // 響應(yīng)中斷,拋出異常后中斷位置會(huì)被復(fù)位,自己中斷自己

                    Thread.currentThread().interrupt();

                    // 這里調(diào)用isInterrupted()獲取當(dāng)前的中斷標(biāo)志

                    System.out.println(Thread.currentThread().getName()

                            +" interrupted flag is " + Thread.currentThread().isInterrupted());

                }

            }

        }

    }



}

輸出結(jié)果:

這里證明interrupted()不清楚中斷標(biāo)志,線程在獲取到 thread.interrupt()發(fā)起中斷后,執(zhí)行結(jié)束。

將上述catch中的Thread.currentThread().isInterrupted()修改為Thread.interrupted()再次運(yùn)行

package com.liziba.p7;

import java.util.concurrent.TimeUnit;



/**

 * <p>

 *

 * </p>

 *

 * @Author: Liziba

 * @Date: 2021/6/24 21:23

 */

public class ThreadInterruptDemo2 {





    public static void main(String[] args) throws InterruptedException {



        Thread thread = new Thread(new Runner(), "Thread-1");

        thread.start();

        TimeUnit.SECONDS.sleep(2);

        thread.interrupt();

    }



    // 區(qū)別在catch中

    static class Runner implements Runnable {



        @Override

        public void run() {

            System.out.println(Thread.currentThread().getName() +" interrupted flag is " + Thread.currentThread().isInterrupted());

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    System.out.println(Thread.currentThread().getName() + " is running .");

                    TimeUnit.SECONDS.sleep(1);

                } catch (InterruptedException e) {

                    // 響應(yīng)中斷,拋出異常后中斷位置會(huì)被復(fù)位,自己中斷自己

                    Thread.currentThread().interrupt();

                    // 注意區(qū)別在這里

                    System.out.println(Thread.currentThread().getName()

                            +" interrupted flag is " + Thread.interrupted());

                }

            }

        }

    }



}

輸出結(jié)果:

線程也響應(yīng)到了 thread.interrupt()的中斷,但是由于catch中調(diào)用了Thread.interrupted(),對(duì)中斷標(biāo)志進(jìn)行了清除,所以!Thread.currentThread().isInterrupted()判斷仍然等于true,線程繼續(xù)不斷的運(yùn)行

看到這里,應(yīng)該已經(jīng)理解了這兩個(gè)方法的主要區(qū)別和其使用,最后我們來看下一個(gè)源碼中的使用案例。我們通過觀看AbstractQueuedSynchronizer(AQS)中的await()方法,來看其在源碼中的使用。

public final void await() throws InterruptedException {

    // 判斷當(dāng)前線程是否被中斷,如果被中斷則恢復(fù)中斷標(biāo)志

    if (Thread.interrupted())

        throw new InterruptedException();

    Node node = addConditionWaiter();

    int savedState = fullyRelease(node);

    int interruptMode = 0;

    while (!isOnSyncQueue(node)) {

        LockSupport.park(this);

        if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)

            break;

    }

    if (acquireQueued(node, savedState) && interruptMode != THROW_IE)

        interruptMode = REINTERRUPT;

    if (node.nextWaiter != null) // clean up if cancelled

        unlinkCancelledWaiters();

    if (interruptMode != 0)

        reportInterruptAfterWait(interruptMode);

}

AbstractQueuedSynchronizer(AQS)源碼中使用靜態(tài)Thread.interrupted(),判斷當(dāng)前線程是否被中斷,并恢復(fù)中斷標(biāo)志,如果線程已被中斷則拋出InterruptedException中斷異常。清除標(biāo)志位的作用就是為了當(dāng)前線程響應(yīng)過中斷后,再次進(jìn)入的時(shí)候可以進(jìn)行后續(xù)操作。

到此這篇關(guān)于Java中的interrupted()isInterrupted()的文章就介紹到這了,更多相關(guān)interrupted()和isInterrupted()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

右玉县| 海盐县| 卫辉市| 南溪县| 江源县| 商水县| 北海市| 普兰店市| 仁寿县| 莎车县| 繁昌县| 梓潼县| 贵阳市| 平果县| 沙洋县| 昭通市| 清丰县| 灵山县| 兰溪市| 辛集市| 天峨县| 于都县| 定州市| 巨鹿县| 忻城县| 运城市| 文昌市| 新昌县| 郴州市| 元朗区| 东至县| 龙山县| 沧州市| 德格县| 左云县| 肥城市| 元阳县| 安国市| 绍兴市| 都江堰市| 读书|