日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AtomicIntegerFieldUpdater字段原子更新类

發布時間:2024/4/13 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AtomicIntegerFieldUpdater字段原子更新类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面講的兩個AtomicInteger和AtomicIntegerArray,這兩個都是在最初設計編碼時候就已經考慮到了需要保證原子性。但是往往有很多情況就是,由于需求的更改,原子性需要在后面加入,類似于我不要求你這整個類操作具有原子性,我只要求你里面一個字段操作具有原子性。沒錯,concurrent.atomic包下AtomicIntegerFieldUpdater就是這個作用的。

AtomicXXXFieldUpdater主要包括以下幾個:AtomicIntegerFieldUpdaterAtomicLongFieldUpdaterAtomicReferenceFieldUpdater

What is AtomicIntegerFieldUpdater

相信前言部分講的已經很清晰易懂了,AtomicIntegerFieldUpdater就是用來更新某一個實例對象里面的int屬性的。
但是注意,在用法上有規則:

  • ?字段必須是volatile類型的,在線程之間共享變量時保證立即可見
  • ?字段的描述類型(修飾符public/protected/default/private)是與調用者與操作對象字段的關系一致。也就是說調用者能夠直接操作對象字段,那么就可以反射進行原子操作。
  • 對于父類的字段,子類是不能直接操作的,盡管子類可以訪問父類的字段。
  • 只能是實例變量,不能是類變量,也就是說不能加static關鍵字。
  • 只能是可修改變量,不能使final變量,因為final的語義就是不可修改。
  • 對于AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long類型的字段,不能修改其包裝類型(Integer/Long)。如果要修改包裝類型就需要使用AtomicReferenceFieldUpdater。

具體規則可以通過以下測試例子來分析:

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntegerFieldUpdaterAnalyzeTest {

??? public static void main(String[] args) {
??????? AtomicIntegerFieldUpdaterAnalyzeTest test = new AtomicIntegerFieldUpdaterAnalyzeTest();
??????? test.testValue();
??? }

??? public AtomicIntegerFieldUpdater<DataDemo> updater(String name) {
??????? return AtomicIntegerFieldUpdater.newUpdater(DataDemo.class, name);
??? }

??? public void testValue() {
??????? DataDemo data = new DataDemo();
//????? //訪問父類的public 變量,報錯:java.lang.NoSuchFieldException
//????? System.out.println("fatherVar = "+updater("fatherVar").getAndIncrement(data));
//???? ?
//????? //訪問普通 變量,報錯:java.lang.IllegalArgumentException: Must be volatile type
//????? System.out.println("intVar = "+updater("intVar").getAndIncrement(data));

//????? //訪問public volatile int 變量,成功
//????? System.out.println("publicVar = "+updater("publicVar").getAndIncrement(data));
//???? ?
//????? //訪問protected volatile int 變量,成功
//????? System.out.println("protectedVar = "+updater("protectedVar").getAndIncrement(data));
//???? ?
//????? //訪問其他類private volatile int變量,失敗:java.lang.IllegalAccessException
//????? System.out.println("privateVar = "+updater("privateVar").getAndIncrement(data));
//???? ?
//????? //訪問,static volatile int,失敗,只能訪問實例對象:java.lang.IllegalArgumentException
//????? System.out.println("staticVar = "+updater("staticVar").getAndIncrement(data));
//???? ?
//????? //訪問integer變量,失敗, Must be integer type
//????? System.out.println("integerVar = "+updater("integerVar").getAndIncrement(data));
//???? ?
//????? //訪問long 變量,失敗, Must be integer type
//????? System.out.println("longVar = "+updater("longVar").getAndIncrement(data));

??????? //自己在自己函數里面可以訪問自己的private變量,所以如果可見,那么可以進行原子性字段更新
??????? data.testPrivate();
??? }
}
class Father{
??? public volatile int fatherVar = 4;
}
class DataDemo extends Father {

??? public int intVar = 4;? //必須是volatile

??? public volatile int publicVar = 3;
??? protected volatile int protectedVar = 4;
??? private volatile int privateVar = 5;

??? public volatile static int staticVar = 10;
??? //The field finalVar can be either final or volatile, not both
??? //public final volatile int finalVar = 11;

??? public volatile Integer integerVar = 19;
??? public volatile Long longVar = 18L;

??? public void testPrivate(){
??????? DataDemo data = new DataDemo();
??????? System.out.println(AtomicIntegerFieldUpdater.newUpdater(DataDemo.class, "privateVar").getAndIncrement(data));
??? }

實現

首先看定義:

/**
?* 允許一個已經定義的類里面的某一個volatile int型變量的原子更新。
?* 注意只能夠原子更新里面的某一個int型的變量。
?* 思路是通過反射獲取變量,為一個updater,然后進行更新。
?*/
public abstract class AtomicIntegerFieldUpdater<T>

AtomicIntegerFieldUpdater是一個抽象類,但是它內部有一個private final類型的默認子類,所以在調用newUpdater的時候,會用模式子類來實現:

/**
???? * 創建一個updater,
???? * tclass:包含類的名稱
???? * fieldName:字段名字
???? */
??? @CallerSensitive
??? public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
????????????????????????????????????????????????????????????? String fieldName) {
??????? return new AtomicIntegerFieldUpdaterImpl<U> (tclass, fieldName, Reflection.getCallerClass());
??? }

?而除了這些之外,子類中還有判斷對象訪問權限,以及判斷是否為父類,是否同一個包等方法:

?

//判斷second是否為first的父類
private static boolean isAncestor(ClassLoader first, ClassLoader second) ;
//判斷class1和class2是否在同一個包下
private static boolean isSamePackage(Class<?> class1, Class<?> class2)
//獲得包名
private static String getPackageName(Class<?> cls)
//判斷object是否為當前class的一個子類
private final void accessCheck(T obj)

另外就是一些CAS方法,實際上都是調用Unsafe.java中的native方法:

?public final boolean compareAndSet(T obj, int expect, int update) {
??????????? accessCheck(obj);
??????????? return U.compareAndSwapInt(obj, offset, expect, update);
??????? }

??????? public final boolean weakCompareAndSet(T obj, int expect, int update) {
??????????? accessCheck(obj);
??????????? return U.compareAndSwapInt(obj, offset, expect, update);
??????? }

??????? public final void set(T obj, int newValue) {
??????????? accessCheck(obj);
??????????? U.putIntVolatile(obj, offset, newValue);
??????? }

??????? public final void lazySet(T obj, int newValue) {
??????????? accessCheck(obj);
??????????? U.putOrderedInt(obj, offset, newValue);
??????? }

??????? public final int get(T obj) {
??????????? accessCheck(obj);
??????????? return U.getIntVolatile(obj, offset);
??????? }

??????? public final int getAndSet(T obj, int newValue) {
??????????? accessCheck(obj);
??????????? return U.getAndSetInt(obj, offset, newValue);
??????? }

AtomicLongFieldUpdater和AtomicReferenceFieldUpdater

在AtomicLongFieldUpdater類中,由于有些32位系統一次性無法對64位的long進行原子運算,所以為了保證安全,在這些不能一次性進行原子運算的需要區分考慮,利用加synchronized鎖來實現:

?

? @CallerSensitive
??? public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
?????????????????????????????????????????????????????????? String fieldName) {
??????? Class<?> caller = Reflection.getCallerClass();
??????? if (AtomicLong.VM_SUPPORTS_LONG_CAS)
??????? //直接cas實現
??????????? return new CASUpdater<U>(tclass, fieldName, caller);
??????? else
??????? //帶synchronized鎖實現
??????????? return new LockedUpdater<U>(tclass, fieldName, caller);
??? }

什么意思呢?下面給出幾個具體方法:

直接CAS實現:

????? //直接CAS實現
??????? public final boolean compareAndSet(T obj, long expect, long update) {
??????????? accessCheck(obj);
??????????? return U.compareAndSwapLong(obj, offset, expect, update);
??????? }

加鎖的CAS實現:

??????? //加鎖的CAS實現
??????? public final boolean compareAndSet(T obj, long expect, long update) {
??????????? accessCheck(obj);
??????????? synchronized (this) {
??????????????? long v = U.getLong(obj, offset);
??????????????? if (v != expect)
??????????????????? return false;
??????????????? U.putLong(obj, offset, update);
??????????????? return true;
??????????? }
??????? }

在其他方面, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater實現思想基本一致。

參考資料:
http://blog.csdn.net/u010412719/article/details/52068888
---------------------
作者:6點A君
來源:CSDN
原文:https://blog.csdn.net/anLA_/article/details/78662383
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

總結

以上是生活随笔為你收集整理的AtomicIntegerFieldUpdater字段原子更新类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。