2015-11-13 18 views
6

:Java Hafıza Görünürlük aşağıdaki basitleştirilmiş sınıf için

public class MutableInteger { 
    private int value; 
    public MutableInteger(int initial) { 
     synchronized(this) { // is this necessary for memory visibility? 
      this.value = initial; 
     } 
    } 
    public synchronized int get() { 
     return this.value; 
    } 
    public synchronized void increment() { 
     this.value++; 
    } 
    ... 
} 

Ben genel soru, yapıcı içinde başlangıç ​​değeri ayarlarken senkronize edilmesi gereklidir senkronizasyon tarafından korunan değişken değişkenler için sanırım?

+0

Neyi başarmaya çalışıyorsunuz? – biziclop

+1

Yapılandırılırken aynı örnekte iki iş parçacığının olabileceğini göremiyorum, bu yüzden hayır diyorum. Eğer değer belki de statikse, ancak bu referansı değil, sınıf nesnesinde senkronize etmeniz gerekir. – Pace

+1

@biziclop Sadece tüm kodlarım iş parçacığı güvenliği ve java bellek modelini daha iyi anlamak için doğru olduğundan emin olmaya çalışıyorum. – nikdeapen

cevap

3

Haklısınız, synchronized yapıcıda blok yokken, this example'da görüldüğü gibi final dışı alanlar için görünürlük garantisi yoktur.

Ancak, pratikte, böyle durumlarda volatile alanlarını veya Atomic* sınıflarını kullanmayı tercih ediyorum.

Güncelleme: O (JLS tarafından tanımlandığı gibi) programınızı correctly synchronized olmak için sırayla, güvenli bir şekilde sizin nesnesine başvuru yayınlamanız gerekir olduğunu burada belirtmek de önemlidir. Atıf edilen örnek bunu yapmaz, dolayısıyla niçin final olmayan alanlarda yanlış değeri görebilirsiniz. Ancak, nesne başvurusunu doğru bir şekilde yayınlarsanız (başka bir nesnenin final alanına atayarak veya Thread.start() numaralı telefonu aramadan önce oluşturarak), nesnenizin en az saat kadar güncel görünmesi garanti edilir. Yayıncılık, bu nedenle yapıcıda synchronized bloğunu gereksiz hale getiriyor.

+0

Teşekkürler, aradığım şey buydu. Bu durumda atomik sınıfları kesinlikle kullanırdım, ancak bu sadece basit durumlarda işe yarar. – nikdeapen

+0

Eğer Java spesifikasyonlarında kendi gözlerimle görmediysem, sana yalancı derim. Tamam, Daily WTF'de bunun hakkında yazı yayınlama zamanı. – Powerlord

+0

@Powerlord Bence, modern VM'lerin çoğu, bir kurucunun sonunda bir bellek bariyeri oluşturuyor, ancak garantili olmamak gerçekten garip görünüyor. Ancak bir kurucu ve diğer yazarlar için bir kurala sahip olmak muhtemelen daha da kafa karıştırıcı olabilir. – biziclop