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

教你如何使用Java多線程編程LockSupport工具類

 更新時(shí)間:2021年04月15日 09:40:39   作者:Tony-devj  
在Java工具包中有一個(gè)LockSupport工具類,主要負(fù)責(zé)掛起和喚醒線程,這篇文章主要介紹了教你如何使用Java多線程編程LockSupport工具類,需要的朋友可以參考下

LockSupport類

用于創(chuàng)建鎖和其他同步類的基本線程阻塞原語,此類與使用它的每個(gè)線程關(guān)聯(lián)一個(gè)許可。如果獲得許可,將立即返回對(duì)park的調(diào)用,并在此過程中消耗掉它;否則may會(huì)被阻止。調(diào)用unpark可使許可證可用(如果尚不可用)。(不過與信號(hào)量不同,許可證不會(huì)累積。最多只能有一個(gè)。)
方法park和unpark提供了有效的阻塞和解阻塞線程的方法,這些線程不會(huì)遇到導(dǎo)致已棄用的方法Thread.suspend和Thread.resume無法用于以下問題:由于許可,在調(diào)用park的一個(gè)線程與試圖進(jìn)行unpark的另一個(gè)線程之間的競爭將保留生命力。此外,如果調(diào)用者的線程被中斷并且支持超時(shí)版本,則park將返回。 park方法也可能在其他任何時(shí)間出于“無理由”返回,因此通常必須在循環(huán)中調(diào)用該循環(huán),該循環(huán)在返回時(shí)會(huì)重新檢查條件。從這個(gè)意義上說,park是對(duì)“繁忙等待”的優(yōu)化,它不會(huì)浪費(fèi)太多的時(shí)間,而必須與unpark配對(duì)才能生效。
了解了其作用,我們看看相關(guān)API。

LockSupport.park()

park():除非有許可,否則出于線程調(diào)度目的禁用當(dāng)前線程。
如果許可證可用,則將其消耗掉,并立即返回呼叫;否則,將立即返回該呼叫。出于線程調(diào)度的目的,當(dāng)前線程將被禁用,并處于休眠狀態(tài),直到發(fā)生以下三種情況之一:
1.其他一些線程以當(dāng)前線程為目標(biāo)調(diào)用unpark()方法
2.其他一些線程Threadinterrupt interrupts當(dāng)前線程
3.虛假地調(diào)用返回
源碼:

public static void park() {
    UNSAFE.park(false, 0L);
}

LockSupport都是調(diào)用的UNSAFE的方法,我們先看看park方法

public class LockSupportMain {
    public static void main(String[] args) {
        System.out.println("begin park!");
        LockSupport.park();
        System.out.println("end park!");
    }
}

運(yùn)行結(jié)果:

在這里插入圖片描述

我們調(diào)用了park方法,導(dǎo)致Main線程一直被阻塞,一直沒有結(jié)束,因?yàn)槟J(rèn)的情況下,調(diào)用線程是不持有許可證的,我們?nèi)绾谓鉀Q呢?上面提到過三個(gè)方式,我們一個(gè)一個(gè)的驗(yàn)證。

1.調(diào)用unpack方法獲得許可

unpack():如果給定線程尚不可用,則使它可用。如果線程在park上被阻止,則它將取消阻止。否則,將確保其對(duì)park的下一次調(diào)用不會(huì)阻塞。如果給定線程尚未啟動(dòng),則不能保證此操作完全無效。
源碼:

public static void unpark(Thread thread) {
    if (thread != null)
        UNSAFE.unpark(thread);
}
public class LockSupportMain2 {
    public static void main(String[] args) {
        System.out.println("begin park!");
        LockSupport.unpark(Thread.currentThread());
        LockSupport.park();
        System.out.println("end park!");
    }
}

運(yùn)行結(jié)果:

在這里插入圖片描述

可以看出,當(dāng)前的線程main已經(jīng)釋放了,沒有進(jìn)行阻塞,直接運(yùn)行完成了。
我們創(chuàng)建一個(gè)線程有Main線程進(jìn)行unpark方法將線程在阻塞的情況下,進(jìn)行運(yùn)行。

public class LockSupportMain3 {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("begin start thread name: " + Thread.currentThread().getName() + " park");
                LockSupport.park();
                System.out.println("end start thread name: " + Thread.currentThread().getName() + " park");
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(2000);
        System.out.println("main thread call unpark");
        LockSupport.unpark(thread);
    }

}

運(yùn)行結(jié)果:

在這里插入圖片描述

運(yùn)行結(jié)果可以看出,其他一些線程以當(dāng)前線程為目標(biāo)調(diào)用unpark()方法可以將線程的park導(dǎo)致阻塞的繼續(xù)運(yùn)行。

2.調(diào)用中斷interrupts方法獲得許可

由于park方法不會(huì)告訴你何種原因返回,所以調(diào)用者需要根據(jù)之前調(diào)用park方法的原因,再次檢查條件是否滿足,如果不能滿足,就還需要調(diào)用park方法

public class LockSupportMain4 {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("begin start thread name: " + Thread.currentThread().getName() + " park");
                while (!Thread.currentThread().isInterrupted()) {
                    LockSupport.park();
                }
                System.out.println("end start thread name: " + Thread.currentThread().getName() + " park");
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(2000);
        //通過interrupt方法 讓park阻塞繼續(xù)運(yùn)行
        thread.interrupt();
    }

}

運(yùn)行結(jié)果:

在這里插入圖片描述

由運(yùn)行可以看出,其他一些線程Threadinterrupt interrupts當(dāng)前線程是可以將park阻塞的線程繼續(xù)運(yùn)行。

parkNanos(long nanos)

parkNanos(long nanos):除非允許使用許可,否則在指定的等待時(shí)間內(nèi)禁用用于線程調(diào)度的當(dāng)前線程。
源碼:

public static void parkNanos(long nanos) {
    if (nanos > 0)
        UNSAFE.park(false, nanos);
}
public class LockSupportMain5 {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("begin start thread name: " + Thread.currentThread().getName() + " park");
                LockSupport.parkNanos(3_000_000_000L);
                System.out.println("end start thread name: " + Thread.currentThread().getName() + " park");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

運(yùn)行結(jié)果:

在這里插入圖片描述

三秒之后,阻塞三秒之后繼續(xù)運(yùn)行。

park(Object blocker)

park(Object blocker):除非有許可,否則出于線程調(diào)度目的禁用當(dāng)前線程
源碼:

public static void park(Object blocker) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(false, 0L);
    setBlocker(t, null);
}

這里的blocker對(duì)象是Thread類中的blocker對(duì)象,代碼如下:

//提供給java.util.concurrent.locks.LockSupport.park的當(dāng)前調(diào)用的參數(shù)。
//由(私有)java.util.concurrent.locks.LockSupport.setBlocker設(shè)置使用
//java.util.concurrent.locks.LockSupport.getBlocker進(jìn)行訪問
volatile Object parkBlocker;

parkNanos(Object blocker, long nanos)

源碼:

public static void parkNanos(Object blocker, long nanos) {
    if (nanos > 0) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        UNSAFE.park(false, nanos);
        setBlocker(t, null);
    }
}

parkUntil(Object blocker, long deadline)

parkUntil(Object blocker, long deadline):除非指定許可,否則禁用當(dāng)前線程以進(jìn)行線程調(diào)度,直到指定的期限。
源碼:

public static void parkUntil(Object blocker, long deadline) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(true, deadline);
    setBlocker(t, null);
}

我們使用java API中的例子看看:

public class LockSupportMain6 {
    private final AtomicBoolean locked = new AtomicBoolean(false);
    private final Queue<Thread> waiters
            = new ConcurrentLinkedQueue<Thread>();

    public void lock() {
        boolean wasInterrupted = false;
        Thread current = Thread.currentThread();
        waiters.add(current);

        // 不在隊(duì)列中時(shí)先阻塞或無法獲取鎖定
        while (waiters.peek() != current ||
                !locked.compareAndSet(false, true)) {
            LockSupport.park(this);
            // 等待時(shí)忽略中斷 如果park方法是因?yàn)楸恢袛喽祷?,則忽略中斷,并且重新設(shè)置中斷標(biāo)記,做個(gè)標(biāo)記
            if (Thread.interrupted()) {
                wasInterrupted = true;
            }
        }
        waiters.remove();
        // 退出時(shí)重新聲明中斷狀態(tài)
        if (wasInterrupted)          
        {
            current.interrupt();
        }
    }
    public void unlock() {
        locked.set(false);
        LockSupport.unpark(waiters.peek());
    }
}

有blocker的可以傳遞給開發(fā)人員更多的現(xiàn)場信息,可以查看到當(dāng)前線程的阻塞對(duì)象,方便定位問題

到此這篇關(guān)于教你如何使用Java多線程編程-LockSupport工具類的文章就介紹到這了,更多相關(guān)使用java的LockSupport工具類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaGUI界面實(shí)現(xiàn)頁面跳轉(zhuǎn)方法

    JavaGUI界面實(shí)現(xiàn)頁面跳轉(zhuǎn)方法

    這篇文章主要給大家介紹了關(guān)于JavaGUI界面實(shí)現(xiàn)頁面跳轉(zhuǎn)的相關(guān)資料, GUI是指圖形用戶界面,指采用圖形方式顯示的計(jì)算機(jī)操作用戶界面,需要的朋友可以參考下
    2023-07-07
  • Java設(shè)計(jì)模式之備忘錄模式(Memento模式)介紹

    Java設(shè)計(jì)模式之備忘錄模式(Memento模式)介紹

    這篇文章主要介紹了Java設(shè)計(jì)模式之備忘錄模式(Memento模式)介紹,memento是一個(gè)保存另外一個(gè)對(duì)象內(nèi)部狀態(tài)拷貝的對(duì)象,這樣以后就可以將該對(duì)象恢復(fù)到原先保存的狀態(tài),需要的朋友可以參考下
    2015-03-03
  • 帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表

    帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表

    這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Java實(shí)現(xiàn)兩人五子棋游戲(三) 畫出棋子

    Java實(shí)現(xiàn)兩人五子棋游戲(三) 畫出棋子

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)兩人五子棋游戲,畫出五子棋的棋子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Java人機(jī)猜拳實(shí)現(xiàn)的思路及方法實(shí)例

    Java人機(jī)猜拳實(shí)現(xiàn)的思路及方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于Java人機(jī)猜拳實(shí)現(xiàn)的思路及方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 在Java中去除字符串末尾的換行符的常用方法小結(jié)

    在Java中去除字符串末尾的換行符的常用方法小結(jié)

    在日常開發(fā)中,字符串操作是非常常見的需求,其中去除字符串末尾的換行符(\n)是一個(gè)很有代表性的場景,本文將從 Java 的幾種常用方法著手,全面解析如何去除字符串末尾的換行符,并結(jié)合代碼示例和實(shí)際使用場景,幫助大家掌握這一技巧,需要的朋友可以參考下
    2024-12-12
  • 深入了解Java設(shè)計(jì)模式之策略模式

    深入了解Java設(shè)計(jì)模式之策略模式

    策略模式屬于Java-設(shè)計(jì)模式中行為模式之一,該模式定義了一系列算法,并將每個(gè)算法封裝起來,使它們可以相互替換。本文將通過示例詳細(xì)講解這一模式,需要的可以參考一下
    2022-09-09
  • 詳解Java中Javassist的使用

    詳解Java中Javassist的使用

    常用的一些操作字節(jié)碼的技術(shù)有?ASM、AspectJ、Javassist?等。本文主要為大家介紹了Javassist使用的相關(guān)知識(shí),感興趣的小伙伴可以了解一下
    2023-04-04
  • 詳解shiro緩存機(jī)制

    詳解shiro緩存機(jī)制

    Shiro提供了類似于Spring的Cache抽象,即Shiro本身不實(shí)現(xiàn)Cache,但是對(duì)Cache進(jìn)行了又抽象,方便更換不同的底層Cache實(shí)現(xiàn)。下面通過實(shí)例代碼給大家分享shiro緩存機(jī)制,感興趣的朋友一起看看吧
    2017-09-09
  • 解決Spring國際化文案占位符失效問題的方法

    解決Spring國際化文案占位符失效問題的方法

    本篇文章主要介紹了解決Spring國際化文案占位符失效問題的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04

最新評(píng)論

盘山县| 佛山市| 遂溪县| 甘泉县| 九江市| 弥勒县| 盘锦市| 武城县| 姚安县| 广州市| 嘉禾县| 皮山县| 景谷| 扎赉特旗| 宁陵县| 大新县| 丽江市| 外汇| 乌拉特后旗| 濮阳县| 开平市| 苍南县| 成都市| 永安市| 故城县| 太保市| 金塔县| 玉树县| 大理市| 鸡东县| 昭苏县| 夹江县| 右玉县| 阿克苏市| 三亚市| 阳城县| 巨野县| 六安市| 甘洛县| 龙胜| 拜泉县|