欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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是一個對象,用于指定阻塞哪個對象。不知道的情況,默認以鎖對象自己this為blocker

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

拓展parkNanos函數

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

nanos參數表示相對時間,表示等待多長時間

parkUntil函數:表示在指定的時限前禁用當前線程,deadline參數表示絕對時間,表示指定的時間

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

unBlock線程類:unpack(Thread)

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

3、LockSupport本質

LockSupport是一個許可的信號量機制,pack消費,unpack放入,放入也是僅一個,不累計。例如,調用unpack放入一個信號量,多次調用,這個是不會累計信號量的,pack調用之后會消費

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();
    }
}

打印:

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實例
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            // 線程類的class對象
            Class<?> tk = Thread.class;
            // 獲取Thread的parkBlocker字段的內存偏移地址
            parkBlockerOffset = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("parkBlocker"));
            // 獲取Thread的threadLocalRandomSeed字段的內存偏移地址
            SEED = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSeed"));
            // 獲取Thread的threadLocalRandomProbe字段的內存偏移地址
            PROBE = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomProbe"));
            // 獲取Thread的threadLocalRandomSecondarySeed字段的內存偏移地址
            SECONDARY = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
        } catch (Exception ex) { throw new Error(ex); }
    }
}

pack方法的源碼:

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

unpack的源碼:

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

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

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

主要提供如下操作:

  • 線程掛起與恢復
  • CAS操作
  • 操縱對象屬性
  • 操縱數組元素
  • 直接操縱內存

總結

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

相關文章

  • Java實現(xiàn)冒泡排序算法及對其的簡單優(yōu)化示例

    Java實現(xiàn)冒泡排序算法及對其的簡單優(yōu)化示例

    這篇文章主要介紹了Java實現(xiàn)冒泡排序算法及對其的簡單優(yōu)化示例,冒泡排序的最差時間復雜度為O(n^2),最優(yōu)時間復雜度為O(n),存在優(yōu)化的余地,需要的朋友可以參考下
    2016-05-05
  • java設計模式學習之工廠方法模式

    java設計模式學習之工廠方法模式

    這篇文章主要介紹了java設計模式學習之工廠方法模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SpringMVC---配置與使用的示例

    SpringMVC---配置與使用的示例

    這篇文章主要介紹了SpringMVC---配置與使用的示例,幫助大家更好的理解和學習spring框架,感興趣的朋友可以了解下
    2020-10-10
  • IDEA JeeSite框架httpSession.invalidate()無效問題解決方案

    IDEA JeeSite框架httpSession.invalidate()無效問題解決方案

    這篇文章主要介紹了IDEA JeeSite框架httpSession.invalidate()無效問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot集成MyBatis對管理員的查詢操作

    SpringBoot集成MyBatis對管理員的查詢操作

    本文主要介紹了SpringBoot集成MyBatis對管理員的查詢操作,實現(xiàn)增刪改查中的查詢操作,對所有的普通管理員進行查詢操作,感興趣的可以了解一下
    2023-11-11
  • Java編程中的4種代碼塊詳解

    Java編程中的4種代碼塊詳解

    在本篇內容里小編個總結了Java編程中的4種代碼塊相關的知識點,有興趣的朋友們可以學習下。
    2021-06-06
  • Spring MVC創(chuàng)建項目踩過的bug

    Spring MVC創(chuàng)建項目踩過的bug

    這篇文章主要介紹了Spring MVC創(chuàng)建項目踩過的bug,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • JVM教程之Java代碼編譯和執(zhí)行的整個過程(二)

    JVM教程之Java代碼編譯和執(zhí)行的整個過程(二)

    這篇文章主要介紹了JVM學習筆記第二篇,關于Java代碼編譯和執(zhí)行的整個過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Java打亂ArrayList生成一個隨機序列列表

    Java打亂ArrayList生成一個隨機序列列表

    有時候會需要將一個ArrayList或者數組中的數字打亂,方便后續(xù)使用,比如隨機出題、答案選項打亂、連線題打亂、抽獎號碼打亂等等,把我自己寫的一段代碼貼出來分享給大家。
    2016-08-08
  • java 方法泛型入參T和String的重載關系詳解

    java 方法泛型入參T和String的重載關系詳解

    這篇文章主要介紹了java 方法泛型入參T和String的重載關系詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評論