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

Java使用Unsafe類的示例詳解

 更新時間:2021年09月25日 09:58:39   作者:Dongguo丶  
java不能直接訪問操作系統(tǒng)底層,而是通過本地方法來訪問。Unsafe類提供了硬件級別的原子操作,這篇文章主要介紹了Java使用Unsafe類,需要的朋友可以參考下

Unsafe 對象提供了非常底層的,操作內(nèi)存、線程的方法,相當(dāng)于開了后門。

在atomic類中CAS實現(xiàn)、LockSupport中park unpark的底層都調(diào)用了UnSafe中的方法。

UnSafe并不是說線程不安全,而是說操作內(nèi)存有可能會造成不安全問題。

當(dāng)然對于開發(fā)人員來說

Unsafe 對象不能直接調(diào)用,只能通過反射獲得

image-20210912213306520

通過反射獲得Unsafe對象

package com.dongguo.unsafe;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author Dongguo
 * @date 2021/9/12 0012-21:32
 * @description:
 */
public class UnsafeAccessor {
    static Unsafe unsafe;
    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new Error(e);
        }
    }
    static Unsafe getUnsafe() {
        return unsafe;
    }

    public static void main(String[] args) {
        Unsafe unsafe = getUnsafe();
        System.out.println(unsafe);
    }
}

運行結(jié)果

sun.misc.Unsafe@7ea987ac

使用Unsafe實現(xiàn) CAS 操作

package com.dongguo.unsafe;

import lombok.Data;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author Dongguo
 * @date 2021/9/12 0012-21:32
 * @description:
 */
public class UnsafeAccessor {
    static Unsafe unsafe;
    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new Error(e);
        }
    }
    static Unsafe getUnsafe() {
        return unsafe;
    }

    public static void main(String[] args) throws NoSuchFieldException {
        Unsafe unsafe = getUnsafe();
        System.out.println(unsafe);

        Field id = Student.class.getDeclaredField("id");
        Field name = Student.class.getDeclaredField("name");
        // 獲得成員變量的偏移量
        long idOffset = unsafe.objectFieldOffset(id);
        long nameOffset = unsafe.objectFieldOffset(name);
        Student student = new Student();
        // 使用 cas 方法替換成員變量的值
        unsafe.compareAndSwapInt(student, idOffset, 0, 20); // 返回 true   0為舊值 20為新值
        unsafe.compareAndSwapObject(student, nameOffset, null, "張三"); // 返回 true 舊值為null,新值為張三
        System.out.println(student);
    }
}
@Data
class Student {
    volatile int id;
    volatile String name;
}

運行結(jié)果

sun.misc.Unsafe@7ea987ac
Student(id=20, name=張三)

直接使用Unsafe類實現(xiàn)之前AtomicIntegerFieldUpdater中線程安全的原子整數(shù) BankAccount

在atomic中使用AtomicIntegerFieldUpdater實現(xiàn)money線程安全的原子整數(shù)

package com.dongguo.unsafe;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * @author Dongguo
 * @date 2021/9/7 0007-14:41
 * 以一種線程安全的方式操作非線程安全對象的某些字段。
 * 需求:
 * 1000個人同時向一個賬號轉(zhuǎn)賬一元錢,那么累計應(yīng)該增加1000元,
 * 除了synchronized和CAS,還可以使用AtomicIntegerFieldUpdater來實現(xiàn)。
 */
class BankAccount {
    private String bankName = "ACBC";
    public volatile int money = 0;
    AtomicIntegerFieldUpdater<BankAccount> fieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankAccount.class, "money");

    public void transferMoney(BankAccount bankAccount) {
        fieldUpdater.incrementAndGet(bankAccount);
    }
}

public class AtomicIntegerFieldUpdaterDemo {
    public static void main(String[] args) {
        BankAccount bankAccount = new BankAccount();

        for (int i = 1; i <= 1000; i++) {
            new Thread(() -> {
                bankAccount.transferMoney(bankAccount);
            }, String.valueOf(i)).start();
        }
        //暫停毫秒
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(bankAccount.money);
    }

}

改為使用UnSafe實現(xiàn)money線程安全的原子整數(shù)

package com.dongguo.unsafe;

import sun.misc.Unsafe;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * @author Dongguo
 * @date 2021/9/7 0007-14:41
 */
class BankAccount {
    private String bankName = "ACBC";
    public volatile int money;
    static final Unsafe unsafe;
    static final long DATA_OFFSET;

    static {
        unsafe = UnsafeAccessor.getUnsafe();
        try {
            // money 屬性在 BankAccount 對象中的偏移量,用于 Unsafe 直接訪問該屬性
            DATA_OFFSET = unsafe.objectFieldOffset(BankAccount.class.getDeclaredField("money"));
        } catch (NoSuchFieldException e) {
            throw new Error(e);
        }
    }

    public BankAccount(int money) {
        this.money = money;
    }

    public void transferMoney(int amount) {
        int oldValue;
        while (true) {
            // 獲取共享變量舊值,可以在這一行加入斷點,修改 data 調(diào)試來加深理解
            oldValue = money;
            // cas 嘗試修改 data 為 舊值 + amount,如果期間舊值被別的線程改了,返回 false
            if (unsafe.compareAndSwapInt(this, DATA_OFFSET, oldValue, oldValue + amount)) {
                return;
            }
        }
    }
}
public class AtomicIntegerFieldUpdaterDemo {
    public static void main(String[] args) {
        BankAccount bankAccount = new BankAccount(0);

        for (int i = 1; i <= 1000; i++) {
            new Thread(() -> {
                bankAccount.transferMoney(1);
            }, String.valueOf(i)).start();
        }
        //暫停毫秒
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(bankAccount.money);
    }
}
運行結(jié)果
1000
/暫停毫秒
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(bankAccount.money);
    }
}

運行結(jié)果

1000

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

相關(guān)文章

  • 基于mybatis like %%的問題

    基于mybatis like %%的問題

    這篇文章主要介紹了mybatis like %%的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • IDEA中Javaweb項目圖片加載不出來解決方案

    IDEA中Javaweb項目圖片加載不出來解決方案

    在IDEA中能夠正常的預(yù)覽到圖片,但是在生成項目的war包時,項目的目錄結(jié)構(gòu)卻會發(fā)生變化,所以無法訪問圖片,本文主要介紹了IDEA中Javaweb項目圖片加載不出來解決方案,感興趣的可以了解一下
    2023-10-10
  • Callable實現(xiàn)多線程步驟詳解

    Callable實現(xiàn)多線程步驟詳解

    這篇文章主要介紹了Callable實現(xiàn)多線程步驟詳解,Callable是一個接口,用于實現(xiàn)多線程,與實現(xiàn)Runnable類似,但是功能更強大,該方法可以在任務(wù)結(jié)束后提供一個返回值,需要的朋友可以參考下
    2023-10-10
  • SpringMVC整合kinfe4j及問題解決分析

    SpringMVC整合kinfe4j及問題解決分析

    這篇文章主要為大家介紹了SpringMVC整合kinfe4j及問題解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 零基礎(chǔ)寫Java知乎爬蟲之進階篇

    零基礎(chǔ)寫Java知乎爬蟲之進階篇

    前面幾篇文章,我們都是簡單的實現(xiàn)了java爬蟲抓取內(nèi)容的問題,那么如果遇到復(fù)雜情況,我們還能繼續(xù)那么做嗎?答案當(dāng)然是否定的,之前的僅僅是入門篇,都是些基礎(chǔ)知識,給大家練手用的,本文我們就來點高大上的東西
    2014-11-11
  • 詳解java中各類鎖的機制

    詳解java中各類鎖的機制

    這篇文章為大家總結(jié)了java中常見的鎖(互斥鎖、讀寫鎖、公平鎖與非公平鎖等)的機制以及如何使用,文中示例代碼講解詳細,需要的可以學(xué)習(xí)一下
    2021-12-12
  • SpringBoot解決跨域問題的五種方案

    SpringBoot解決跨域問題的五種方案

    跨域問題指的是不同站點之間,使用 ajax 無法相互調(diào)用的問題,跨域問題本質(zhì)是瀏覽器的一種保護機制,它的初衷是為了保證用戶的安全,防止惡意網(wǎng)站竊取數(shù)據(jù),那怎么解決這個問題呢?接下來我們一起來看,需要的朋友可以參考下
    2024-07-07
  • 解決Java 部署Tomcat時使用jni和jna調(diào)用DLL文件的問題

    解決Java 部署Tomcat時使用jni和jna調(diào)用DLL文件的問題

    這篇文章主要介紹了解決Java 部署Tomcat時使用jni和jna調(diào)用DLL文件的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Springboot中MyBatisplus使用IPage和Page分頁的實例代碼

    Springboot中MyBatisplus使用IPage和Page分頁的實例代碼

    這篇文章主要介紹了Springboot中MyBatisplus使用IPage和Page分頁,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • java中final修飾符實例分析

    java中final修飾符實例分析

    本文通過實例向我們展示了java中final修飾符的概念,final修飾的基本變量和引用類型變量的區(qū)別。有需要的小伙伴可以參考下
    2014-11-11

最新評論

华容县| 绥滨县| 阳泉市| 西吉县| 宝丰县| 灯塔市| 遵义市| 永年县| 新建县| 阿瓦提县| 社会| 左贡县| 神木县| 甘德县| 隆尧县| 滁州市| 张家界市| 金溪县| 康乐县| 五常市| 茌平县| 漳州市| 新竹市| 庄河市| 兰坪| 元谋县| 平度市| 威远县| 沁水县| 洞头县| 洞头县| 巴林左旗| 南溪县| 静海县| 金沙县| 天全县| 布拖县| 平陆县| 博白县| 赣州市| 婺源县|