面試官問我 volatile 是否存在僞共享問題?我懵逼了

Photo By Instagram sooyaaa

昨天的問題

往期問題中,我們介紹了 LongAdder 工具類。我們知道了 LongAdder 中爲了分散熱點數據,存在一個 volatile 修飾的 Cell 數組。由於數組的連續存儲特性,會存在僞共享問題,你知道 LongAdder 是如何解決的嗎?

我的答案

在探討 LongAdder 是如何解決僞共享問題之前,我們要先梳理清一個概念,什麼是 僞共享 共享

共享在 Java 編程裏面我們可以這樣理解,有一個 Share 類,它有一個 value 的屬性。如下:

public class Share {
   int value;
}

我們初始化 Share 的一個實例,然後啓動多個線程去操作它的 value 屬性,此時的 Share 變量被多個線程操作的這種情況我們稱之爲 共享

大家都知道在不添加任何互斥措施的情況,多線程操作這個 Share 變量的 value 屬性肯定存在線程安全性的問題。那有什麼辦法可以解決這個問題呢?我們可以使用 volatile 和 CAS 技術來保證共享變量可以安全的被多個線程共享操作使用,不知道 volatile 和 CAS 技術點的同學可以參考往期文章 ReentranLock 實現原理居然是這樣?

但是由於 volatile 的引入,會帶來一些問題。大家都知道 JMM(Java 內存模型)規範了 volatile 具有內存可見性和禁止指令重排序的語義。這倆條語義使得某個線程更新本地緩存中的 value 值後會將其他線程的本地緩存中的 value 值失效,然後其他線程再次讀取 value 值的時候需要去主存裏面獲取 value 值,這樣即保證了 value 的內存可見性。

當然啦,這沒有任何問題,但是由於線程本地緩存的操作是以緩存行爲單位的,一個緩存行大小通常爲 64B(不同型號的電腦緩存行大小會有不同)。因此一個緩存行中不會只單單存儲 value 一個變量,可能還會存儲其他變量。這樣當一個線程更新了 value 之後,如果其他線程本地緩存中同樣緩存了 value, value 所在的緩存行就會失效,這意味着該緩存行上的其他變量也會失效,那麼線程對這個該緩存行上所有變量的訪問都需要從主存中獲取。我們都知道 CPU 訪問主存的速度相對於訪問緩存的速度有着數量級的差距,這就帶了很大的性能問題,我們將這個問題稱之爲 僞共享

理解了僞共享到底是什麼鬼以後,我們來看看 Java 大師們是怎麼解決這個問題的。在早期版本的 JDK 裏面你應該見到過類似如下的代碼:

public class Share {
    volatile int value;
    long p1, p2, p3, p4, p5, p6;
}

你可能猜到了,定義了幾個無用的變量作爲填充物,他們會保證一個緩存行裏面只保存了 Share 變量,這樣更新 Share 變量的時候就不會存在僞共享問題了。但是這種方法存在什麼問題呢?

首先基於每臺運行 Java 程序的機器的緩存行大小可能不同,其次由於這些類似填充物的變量並沒有被實際使用,可以被 JVM 優化掉,這樣就失效了。

基於此,在 Java 8 的時候,官方給出瞭解決策略,這就是 Contended 註解。依賴於這個註解,我們在 Java 8 環境下可以這樣改善代碼:

public class Share {
    @Contended
    volatile int value;
}

使用如上註解,並且在 JVM 啓動參數中加入 -XX:-RestrictContended,這樣 JVM 在運行時就會自動的爲我們的 Share 類添加合適大小的填充物(padding)來解決僞共享問題,而不需要我們手寫變量來作爲填充物了,這樣就更加便捷優雅的解決了僞共享問題。悄悄的告訴你,LongAdder 就是使用 Contended 來解決僞共享問題噠。

好了,相信你已經瞭解了什麼是僞共享問題,以及早期併發編程大師是如何解決僞共享問題的,最後我們也介紹了在 Java 8 中使用 Contended 來更優雅的解決僞共享問題。Contended 還提供了一個緩存行分組的功能,在上文中我們沒有介紹,歡迎有興趣的小夥伴們自行探索吧(嘿嘿)。

以上即爲昨天的問題的答案,小夥伴們對這個答案是否滿意呢?歡迎留言和我討論。

又要到年末了,你是不是又悄咪咪的開始看機會啦。爲了廣大小夥伴能充足電量,能順利通過 BAT 的面試官無情三連炮,我特意推出大型刷題節目。每天一道題目,第二天給答案,前一天給小夥伴們獨立思考的機會。

點下“在看”,鼓勵一下?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章