亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Java并發(fā)編程-原子類(lèi)實(shí)現(xiàn)

gyl_coder / 846人閱讀

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

前言

為了研究Java對(duì)原子類(lèi)的實(shí)現(xiàn),從AtomicInteger類(lèi)開(kāi)始,分析Java如果對(duì)原子操作的實(shí)現(xiàn)。

什么是原子操作?

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

源碼分析:

首先從AtomicInteger類(lèi)的屬性聊起:

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

該類(lèi)共有三個(gè)成員屬性。

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

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

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

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

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

該過(guò)程實(shí)際上就是計(jì)算成員變量value的內(nèi)存偏移地址,計(jì)算后,可以更直接的對(duì)內(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);

下面看看這個(gè)類(lèi)在JDK中是如何實(shí)現(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
}  

通過(guò)對(duì)象地址和value的偏移量地址,來(lái)計(jì)算value的內(nèi)存地址。

使用自旋鎖來(lái)處理并發(fā)問(wèn)題。

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

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

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

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

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

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

了解常見(jià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實(shí)現(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");
}

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

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

將值賦值給中間變量result。

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

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/70830.html

相關(guān)文章

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

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

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

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

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

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

    NickZhou 評(píng)論0 收藏0
  • BATJ都愛(ài)問(wèn)的多線程面試題

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

    高勝山 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<