国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java使用Unsafe類的示例詳解

Java使用Unsafe類的示例詳解

2022-01-18 16:47Dongguo丶 Java教程

java不能直接訪問操作系統(tǒng)底層,而是通過本地方法來訪問。Unsafe類提供了硬件級別的原子操作,這篇文章主要介紹了Java使用Unsafe類,需要的朋友可以參考下

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

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

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

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

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

Java使用Unsafe類的示例詳解

通過反射獲得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);
  }
}

運行結果

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

運行結果

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個人同時向一個賬號轉賬一元錢,那么累計應該增加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);
  }
}
運行結果
1000
/暫停毫秒
      try {
          TimeUnit.MILLISECONDS.sleep(500);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println(bankAccount.money);
  }
}

運行結果

1000

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

原文鏈接:https://blog.csdn.net/m0_37450089/article/details/120462281

延伸 · 閱讀

精彩推薦
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現(xiàn)搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發(fā)現(xiàn)了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發(fā)項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
主站蜘蛛池模板: 日韩在线一区二区三区 | 欧美亚洲 | 久久99国产精品久久99果冻传媒 | 精品成人久久 | 国产精品综合一区二区 | 国产高清亚洲 | 黄色小视频在线观看 | 精品一区二区三区在线观看 | 在线欧美一区 | 亚洲精品免费视频 | 精品久久久中文字幕 | 日韩在线观看中文字幕 | 国产欧美在线观看 | 日本videos18高清hd下 | 欧美精品黄色 | 91无吗| 久久精品成人 | 中文字幕人成乱码在线观看 | 亚洲精品久久久 | 黄免费 | h视频在线免费观看 | 国产精品一区二区久久 | 欧美日韩综合在线 | 凹凸国产成人精品视频免费 | 欧美久| 日韩在线播放一区二区三区 | 美日韩一区二区三区 | 日韩精品一区二区三区在线 | 91 在线| 色婷婷综合久久久中文字幕 | 亚洲精品视频在线观看网站 | 最新黄色网址在线播放 | 国产精品一区二区三 | 亚洲精品一| 亚洲一区二区在线播放 | 激情婷婷 | 青青草久| 欧美午夜视频 | 国产精品久久久久久久 | 在线观看av网站永久 | 青青草在线视频免费观看 |