成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java并發(fā)編程-原子類實現(xiàn)

gyl_coder / 826人閱讀

摘要:前言為了研究對原子類的實現(xiàn),從類開始,分析如果對原子操作的實現(xiàn)。保存著基礎(chǔ)數(shù)據(jù),使用修飾,可以保證該值對內(nèi)存可見,也是原子類實現(xiàn)的理論保障。使用自旋鎖來處理并發(fā)問題。

前言

為了研究Java對原子類的實現(xiàn),從AtomicInteger類開始,分析Java如果對原子操作的實現(xiàn)。

什么是原子操作?

原子操作是指不會被線程調(diào)度機(jī)制打斷的操作;這種操作一旦開始,就一直運行到結(jié)束,中間不會有任何上下文的切換。
注:原子操作可以是一個步驟,也可以是多個操作步驟,但是其順序不可以被打亂,也不可以被切割只執(zhí)行其中的一部分。

源碼分析:

首先從AtomicInteger類的屬性聊起:

// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
private volatile int value;

該類共有三個成員屬性。

unsafe:該類是JDK提供的可以對內(nèi)存直接操作的工具類。

valueOffset:該值保存著AtomicInteger基礎(chǔ)數(shù)據(jù)的內(nèi)存地址,方便unsafe直接對內(nèi)存的操作。

value:保存著AtomicInteger基礎(chǔ)數(shù)據(jù),使用volatile修飾,可以保證該值對內(nèi)存可見,也是原子類實現(xiàn)的理論保障。

再談靜態(tài)代碼塊(初始化)

    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}

該過程實際上就是計算成員變量value的內(nèi)存偏移地址,計算后,可以更直接的對內(nèi)存進(jìn)行操作。
了解核心方法compareAndSet(int expect,int update):

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

在該方法中調(diào)用了unsafe提供的服務(wù):

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

下面看看這個類在JDK中是如何實現(xiàn)的:

jboolean sun::misc::Unsafe::compareAndSwapInt (jobject obj, jlong offset,jint expect, jint update)  {  
  jint *addr = (jint *)((char *)obj + offset); //1
  return compareAndSwap (addr, expect, update);
}  

static inline bool compareAndSwap (volatile jlong *addr, jlong old, jlong new_val)    {    
  jboolean result = false;    
  spinlock lock;    //2
  if ((result = (*addr == old)))    //3
    *addr = new_val;    //4
  return result;  //5
}  

通過對象地址和value的偏移量地址,來計算value的內(nèi)存地址。

使用自旋鎖來處理并發(fā)問題。

比較內(nèi)存中的值與調(diào)用方法時調(diào)用方所期待的值。

如果3中的比較符合預(yù)期,則重置內(nèi)存中的值。

如果成功置換則返回true,否則返回false;

綜上所述:compareAndSet的實現(xiàn)依賴于兩個條件:

volatile原語:保證在操作內(nèi)存的值時,該值的狀態(tài)為最新的。(被volatile所修飾的變量在讀取值時都會從變量的地址中讀取,而不是從寄存器中讀取,保證數(shù)據(jù)對所有線程都是可見的)

Unsafe類:通過該類提供的功能,可以直接對內(nèi)存進(jìn)行操作。

了解常見操作getAndIncrement():

    return unsafe.getAndAddInt(this, valueOffset, 1);
}

同樣使用unsafe提供的方法:

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);//1
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//2
    return var5;
}
 
//getIntVolatile方法native實現(xiàn)
jint sun::misc::Unsafe::getIntVolatile (jobject obj, jlong offset)    
{    
  volatile jint *addr = (jint *) ((char *) obj + offset);    //3
  jint result = *addr;    //4
  read_barrier ();    //5
  return result;    //6
}  
inline static void read_barrier(){
  __asm__ __volatile__("" : : : "memory");
}

通過volatile方法獲取當(dāng)前內(nèi)存中該對象的value值。

計算value的內(nèi)存地址。

將值賦值給中間變量result。

插入讀屏障,保證該屏障之前的讀操作后后續(xù)的操作可見。

返回當(dāng)前內(nèi)存值

通過compareAndSwapInt操作對value進(jìn)行+1操作,如果再執(zhí)行該操作過程中,內(nèi)存數(shù)據(jù)發(fā)生變更,則執(zhí)行失敗,但循環(huán)操作直至成功。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70830.html

相關(guān)文章

  • Java并發(fā)編程的藝術(shù)】第二章讀書筆記之原子操作

    摘要:前言今天的筆記來了解一下原子操作以及中如何實現(xiàn)原子操作。概念原子本意是不能被進(jìn)一步分割的最小粒子,而原子操作意為不可被中斷的一個或一系列操作。處理器實現(xiàn)原子操作處理器會保證基本內(nèi)存操作的原子性。 showImg(https://segmentfault.com/img/bVVIRA?w=1242&h=536); 前言 今天的筆記來了解一下原子操作以及Java中如何實現(xiàn)原子操作。 概念 ...

    olle 評論0 收藏0
  • Java 8 并發(fā)教程:原子變量和 ConcurrentMa

    摘要:并發(fā)教程原子變量和原文譯者飛龍協(xié)議歡迎閱讀我的多線程編程系列教程的第三部分。如果你能夠在多線程中同時且安全地執(zhí)行某個操作,而不需要關(guān)鍵字或上一章中的鎖,那么這個操作就是原子的。當(dāng)多線程的更新比讀取更頻繁時,這個類通常比原子數(shù)值類性能更好。 Java 8 并發(fā)教程:原子變量和 ConcurrentMap 原文:Java 8 Concurrency Tutorial: Synchroni...

    bitkylin 評論0 收藏0
  • Java并發(fā)編程筆記(二)

    摘要:本文探討并發(fā)中的其它問題線程安全可見性活躍性等等。當(dāng)閉鎖到達(dá)結(jié)束狀態(tài)時,門打開并允許所有線程通過。在從返回時被叫醒時,線程被放入鎖池,與其他線程競爭重新獲得鎖。 本文探討Java并發(fā)中的其它問題:線程安全、可見性、活躍性等等。 在行文之前,我想先推薦以下兩份資料,質(zhì)量很高:極客學(xué)院-Java并發(fā)編程讀書筆記-《Java并發(fā)編程實戰(zhàn)》 線程安全 《Java并發(fā)編程實戰(zhàn)》中提到了太多的術(shù)語...

    NickZhou 評論0 收藏0
  • BATJ都愛問的多線程面試題

    摘要:今天給大家總結(jié)一下,面試中出鏡率很高的幾個多線程面試題,希望對大家學(xué)習(xí)和面試都能有所幫助。指令重排在單線程環(huán)境下不會出先問題,但是在多線程環(huán)境下會導(dǎo)致一個線程獲得還沒有初始化的實例。使用可以禁止的指令重排,保證在多線程環(huán)境下也能正常運行。 下面最近發(fā)的一些并發(fā)編程的文章匯總,通過閱讀這些文章大家再看大廠面試中的并發(fā)編程問題就沒有那么頭疼了。今天給大家總結(jié)一下,面試中出鏡率很高的幾個多線...

    高勝山 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<