簡體   English   中英

易失性同步組合以提高性能

[英]volatile synchronized combination for performance

使用同步時會對性能產生影響。 volatile可以與synchronized結合使用以降低性能開銷嗎? 例如,Counter的實例將在許多線程之間共享,每個線程都可以訪問Counter的公共方法。 在下面的代碼中,volatile用於getter,synchronized用於setter

public class Counter
{
    private volatile int count;

    public Counter()
    {
        count = 0;
    }

    public int getCount()
    {
        return count;
    }

    public synchronized void increment()
    {
        ++count;
    }   
}

請告訴我這可能會破壞的情況?

是的,你絕對可以。 事實上,如果你看一下AtomicInteger的源代碼,它基本上就是他們所做的。 AtomicInteger.get只返回value ,這是一個volatile int鏈接 )。 與你所做的和他們做的唯一真正的區別是他們使用CAS來增加而不是同步。 在現代硬件上,CAS可以消除任何互斥; 在較舊的硬件上,JVM會在增量周圍放置某種互斥。

易失性讀取速度與非易失性讀取速度一樣快,因此讀取速度非常快。

不僅如此,保證不會撕裂volatile區域:參見JLS 17.7 ,它規定了volatile long s和double s不會受到撕裂。 所以你的代碼可以使用longint一樣long

正如迭戈弗雷納所指出的那樣,如果你得到增量發生的“正確”值,你可能看不到增量的結果 - 你會看到之前或之后。 當然,如果get是同步的,那么你從read線程中獲得完全相同的行為 - 你要么看到前遞增值或后遞增值。 所以這兩種方式都是一樣的。 換句話說,說你不會看到正在發生的價值是沒有意義的 - 除非你的意思是撕裂,(a)你不會得到和(b)你永遠不會想要的。

1.我曾親自使用的這種機制volatile 聯合 synchronized

2.可以單獨使用 synchronized ,並且您將始終獲得一致的結果,但僅使用 volatile 不會始終產生相同的結果。

3.這是因為揮發性關鍵字不是原始的同步。 它只是防止在線程上緩存值 ,但它不會阻止兩個線程修改相同的值並同時將其寫回。

4. volatile給予沒有鎖的線程的並發訪問 ,但是然后使用synchronized允許一個線程訪問該類以及類中的所有同步方法。

5. 使用 volatile and synchronized都會這樣做....

volatile -將更改的值反映到線程,並防止緩存,

synchronized -但是使用synchronized關鍵字,將確保只有一個線程可以訪問類的同步方法。

調用getCount()時,您不會總是獲得最實際的計數。 AtomicInteger可能適合您。

使用兩者都不會帶來性能提升。 Volatile保證在通過防止緩存並行執行的線程讀取/寫入變量時變量的值是一致的。 同步 ,當應用於方法時(如您的示例中所做),僅允許單個線程一次輸入該方法並阻止其他方法,直到執行完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM