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

Java使用Unsafe類(lèi)的示例詳解

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

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

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

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

當(dāng)然對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)

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

image-20210912213306520

通過(guò)反射獲得Unsafe對(duì)象

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

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

sun.misc.Unsafe@7ea987ac

使用Unsafe實(shí)現(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;
}

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

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

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

在atomic中使用AtomicIntegerFieldUpdater實(shí)現(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
 * 以一種線程安全的方式操作非線程安全對(duì)象的某些字段。
 * 需求:
 * 1000個(gè)人同時(shí)向一個(gè)賬號(hào)轉(zhuǎn)賬一元錢(qián),那么累計(jì)應(yīng)該增加1000元,
 * 除了synchronized和CAS,還可以使用AtomicIntegerFieldUpdater來(lái)實(shí)現(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實(shí)現(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 對(duì)象中的偏移量,用于 Unsafe 直接訪問(wèn)該屬性
            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) {
            // 獲取共享變量舊值,可以在這一行加入斷點(diǎn),修改 data 調(diào)試來(lái)加深理解
            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);
    }
}
運(yùn)行結(jié)果
1000
/暫停毫秒
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(bankAccount.money);
    }
}

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

1000

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

相關(guān)文章

  • Spring重試支持Spring Retry的方法

    Spring重試支持Spring Retry的方法

    本篇文章主要介紹了Spring重試支持Spring Retry的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • spring boot項(xiàng)目如何采用war在tomcat容器中運(yùn)行

    spring boot項(xiàng)目如何采用war在tomcat容器中運(yùn)行

    這篇文章主要介紹了spring boot項(xiàng)目如何采用war在tomcat容器中運(yùn)行呢,主要講述將SpringBoot打成war包并放入tomcat中運(yùn)行的方法分享,需要的朋友可以參考下
    2022-11-11
  • Java中final關(guān)鍵字和final的4種用法

    Java中final關(guān)鍵字和final的4種用法

    這篇文章主要給大家分享的是?Java中final關(guān)鍵字和final的4種用法修飾類(lèi)、修飾方法、修飾變量、修飾參數(shù),下面文章具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-11-11
  • Java中的static靜態(tài)代碼塊的使用詳解

    Java中的static靜態(tài)代碼塊的使用詳解

    本篇文章介紹了,Java中的static靜態(tài)代碼塊的使用詳解。需要的朋友參考下
    2013-04-04
  • Spring?Boot?Rest常用框架注解詳情簡(jiǎn)介

    Spring?Boot?Rest常用框架注解詳情簡(jiǎn)介

    這篇文章主要介紹了Spring?Boot?Rest常用框架注解,通過(guò)將嘗試解釋Spring?Boot?Rest?API的不同注釋?zhuān)@些注釋是Spring?Boot中REST?API所必需的,需要的朋友可以參考一下
    2022-06-06
  • Java 工具類(lèi)總結(jié)目錄(分享)

    Java 工具類(lèi)總結(jié)目錄(分享)

    下面小編就為大家?guī)?lái)一篇Java 工具類(lèi)總結(jié)目錄(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • MyBatis?Mapper.XML?標(biāo)簽使用小結(jié)

    MyBatis?Mapper.XML?標(biāo)簽使用小結(jié)

    在MyBatis中,通過(guò)resultMap可以解決字段名和屬性名不一致的問(wèn)題,對(duì)于復(fù)雜的查詢(xún),引用實(shí)體或使用<sql>標(biāo)簽可以定義復(fù)用的SQL片段,提高代碼的可讀性和編碼效率,使用這些高級(jí)映射和動(dòng)態(tài)SQL技巧,可以有效地處理復(fù)雜的數(shù)據(jù)庫(kù)交互場(chǎng)景
    2024-10-10
  • spring框架cacheAnnotation緩存注釋聲明解析

    spring框架cacheAnnotation緩存注釋聲明解析

    這篇文章主要介紹了spring框架中cacheAnnotation注釋聲明緩存解析示例有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • 簡(jiǎn)單了解JavaBean作用及常用操作

    簡(jiǎn)單了解JavaBean作用及常用操作

    這篇文章主要介紹了簡(jiǎn)單了解JavaBean作用及常用操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Mybatis查詢(xún)語(yǔ)句返回對(duì)象和泛型集合的操作

    Mybatis查詢(xún)語(yǔ)句返回對(duì)象和泛型集合的操作

    這篇文章主要介紹了Mybatis查詢(xún)語(yǔ)句返回對(duì)象和泛型集合的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論