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

Java并發(fā)編程系列之LockSupport的用法

 更新時間:2021年11月22日 16:26:01   作者:smileNicky  
這篇文章主要為大家介紹了Java LockSupport的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助,希望能夠給你帶來幫助

1、什么是LockSupport?

LockSupport是用于創(chuàng)建鎖和其他同步類的基本線程阻塞原語

2、兩類基本API

LockSupport提供了兩類最基本的API:

block線程類:一般都是以pack開頭的方法名,pack*(...)

pack方法有兩個重載的版本:blocker是一個對象,用于指定阻塞哪個對象。不知道的情況,默認(rèn)以鎖對象自己this為blocker

public static void park();
public static void park(Object blocker);

拓展parkNanos函數(shù)

public static void parkNanos(Object blocker, long nanos) {
    if (nanos > 0) { 
        // 獲取當(dāng)前線程
        Thread t = Thread.currentThread();
        // 設(shè)置Blocker
        setBlocker(t, blocker);
        // 獲取許可,并設(shè)置了時間
        UNSAFE.park(false, nanos);
        // 設(shè)置許可,重新設(shè)置blocker為null,避免unpack,獲取的blocker為之前設(shè)置的
        setBlocker(t, null);
    }
}

nanos參數(shù)表示相對時間,表示等待多長時間

parkUntil函數(shù):表示在指定的時限前禁用當(dāng)前線程,deadline參數(shù)表示絕對時間,表示指定的時間

public static void parkUntil(Object blocker, long deadline) {
    // 獲取當(dāng)前線程
    Thread t = Thread.currentThread();
    // 設(shè)置Blocker
    setBlocker(t, blocker);
    UNSAFE.park(true, deadline);
    // 設(shè)置Blocker為null
    setBlocker(t, null);
}

unBlock線程類:unpack(Thread)

unpack方法用于釋放許可,指定線程可以繼續(xù)運(yùn)行。

3、LockSupport本質(zhì)

LockSupport是一個許可的信號量機(jī)制,pack消費(fèi),unpack放入,放入也是僅一個,不累計。例如,調(diào)用unpack放入一個信號量,多次調(diào)用,這個是不會累計信號量的,pack調(diào)用之后會消費(fèi)

4、LockSupport例子

例子:如何控制兩個線程依次打印1、2、3、4、5、6、…

import java.util.concurrent.locks.LockSupport;
public class LockSupportExample {
    private static final int total = 10;
    private  static int i = 0;
    static Thread t1 , t2;
    public static void main(String[] args) {
        t1 = new Thread(() ->{
            while (i < total) {
                System.out.println("t1:" + (++i));
                LockSupport.unpark(t2);
                LockSupport.park();
            }
        });
        t2 = new Thread(() -> {
            while (i < total) {
                LockSupport.park();
                System.out.println("t2:" + (++i));
                LockSupport.unpark(t1);
            }
        });
        t1.start();
        t2.start();
    }
}

打?。?/p>

t1: 1
t2: 2
t1:3
t2:4
t1:5
t2:6
t1:7
t2:8
t1:9
t2:10

5、LockSupport源碼

public class LockSupport {
    // Hotspot implementation via intrinsics API
    private static final sun.misc.Unsafe UNSAFE;
    private static final long parkBlockerOffset;
    private static final long SEED;
    private static final long PROBE;
    private static final long SECONDARY;
    static {
        try {
            // 獲取Unsafe實(shí)例
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            // 線程類的class對象
            Class<?> tk = Thread.class;
            // 獲取Thread的parkBlocker字段的內(nèi)存偏移地址
            parkBlockerOffset = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("parkBlocker"));
            // 獲取Thread的threadLocalRandomSeed字段的內(nèi)存偏移地址
            SEED = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSeed"));
            // 獲取Thread的threadLocalRandomProbe字段的內(nèi)存偏移地址
            PROBE = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomProbe"));
            // 獲取Thread的threadLocalRandomSecondarySeed字段的內(nèi)存偏移地址
            SECONDARY = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
        } catch (Exception ex) { throw new Error(ex); }
    }
}

pack方法的源碼:

public static void park(Object blocker) {
    // 獲取當(dāng)前線程
    Thread t = Thread.currentThread();
    // 設(shè)置Blocker
    setBlocker(t, blocker);
    // 獲取許可
    UNSAFE.park(false, 0L);
    // 重新可運(yùn)行后再此設(shè)置Blocker為null,避免unpack獲取到上一個設(shè)置的setBlocker(t, blocker);
    setBlocker(t, null);
}

unpack的源碼:

public static void unpark(Thread thread) {
    if (thread != null) // 線程為不空
        UNSAFE.unpark(thread); // 釋放該線程許可
}

可以看出,不管是pack的源碼還是unpack的源碼都是通過Unsafe的底層api實(shí)現(xiàn)的

sun.misc.Unsafe可以直接進(jìn)行底層非安全操作的工具類

主要提供如下操作:

  • 線程掛起與恢復(fù)
  • CAS操作
  • 操縱對象屬性
  • 操縱數(shù)組元素
  • 直接操縱內(nèi)存

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Java實(shí)現(xiàn)warcraft?java版游戲的示例代碼

    Java實(shí)現(xiàn)warcraft?java版游戲的示例代碼

    致敬經(jīng)典的warcraft,《warcraft?java版》是一款即時戰(zhàn)略題材單機(jī)游戲,采用魔獸原味風(fēng)格和機(jī)制。本文將用java語言實(shí)現(xiàn),采用了swing技術(shù)進(jìn)行了界面化處理,感興趣的可以了解一下
    2022-09-09
  • Java多線程案例實(shí)戰(zhàn)之定時器的實(shí)現(xiàn)

    Java多線程案例實(shí)戰(zhàn)之定時器的實(shí)現(xiàn)

    在Java中可以使用多線程和定時器來實(shí)現(xiàn)定時任務(wù),下面這篇文章主要給大家介紹了關(guān)于Java多線程案例之定時器實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Java for循環(huán)詳解

    Java for循環(huán)詳解

    這篇文章主要介紹了Java for循環(huán)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • spring定時任務(wù)執(zhí)行兩次及tomcat部署緩慢問題的解決方法

    spring定時任務(wù)執(zhí)行兩次及tomcat部署緩慢問題的解決方法

    這篇文章主要給大家介紹了關(guān)于spring定時任務(wù)執(zhí)行兩次及tomcat部署緩慢問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • SpringBoot?Security的自定義異常處理

    SpringBoot?Security的自定義異常處理

    這篇文章主要介紹了SpringBoot?Security的自定義異常處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java面試題沖刺第十九天--數(shù)據(jù)庫(4)

    Java面試題沖刺第十九天--數(shù)據(jù)庫(4)

    這篇文章主要為大家分享了最有價值的三道關(guān)于數(shù)據(jù)庫的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • maven?插件?assembly?打tar.gz包的詳細(xì)過程

    maven?插件?assembly?打tar.gz包的詳細(xì)過程

    這篇文章主要介紹了maven插件assembly打tar.gz包的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • SpringBoot ApplicationListener事件監(jiān)聽接口使用問題探究

    SpringBoot ApplicationListener事件監(jiān)聽接口使用問題探究

    這篇文章主要介紹了SpringBoot ApplicationListener事件監(jiān)聽接口使用問題,自定義監(jiān)聽器需要實(shí)現(xiàn)ApplicationListener接口,實(shí)現(xiàn)對應(yīng)的方法來完成自己的業(yè)務(wù)邏輯。SpringBoot Application共支持6種事件監(jiān)聽
    2023-04-04
  • Java使用lambda表達(dá)式簡化代碼的示例詳解

    Java使用lambda表達(dá)式簡化代碼的示例詳解

    這篇文章主要給大家介紹了Java如何使用lambda表達(dá)式簡化代碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-11-11
  • SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請通知流程

    SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請通知流程

    這篇文章主要介紹了 SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請通知流程,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2017-12-12

最新評論

建昌县| 靖安县| 离岛区| 鲁甸县| 铜梁县| 五大连池市| 巴彦县| 松阳县| 澄城县| 扶沟县| 天峻县| 亳州市| 延边| 社旗县| 黄骅市| 新郑市| 本溪| 盘锦市| 资溪县| 康定县| 乐东| 同仁县| 云和县| 孙吴县| 耒阳市| 河源市| 万源市| 桃源县| 阳江市| 光泽县| 漠河县| 南涧| 丰都县| 大新县| 东乡县| 偏关县| 得荣县| 岱山县| 永登县| 乐至县| 吕梁市|