yılında kilitleme atılı 'üzerine Eşzamanlı programlama pencereler'Çift gerekli olduğunu 'uçucu' operasyonu ne tür Joe Duffy kitabından DCL kodunu aldı .NET
class LazyInit<T> where T : class
{
private volatile T m_value;
private object m_sync = new object();
private Func<T> m_factory;
public LazyInit(Func<T> factory) { m_factory = factory; }
public T value
{
get
{
if (m_value == null)
{
lock (m_sync)
{
if (m_value == null)
{
m_value = m_factory();
}
}
}
return m_value;
}
}
}
bu söylenir önleyebilir işaretleme m_value uçucu yeniden başlatmayı, diğer konuların "başlatılmamış alanlarla boş olmayan nesne" oluşturmasına yol açacağını yazar. Sorun sadece olası yazımların yeniden sıralanmasından kaynaklanıyorsa, aşağıdaki gibi dosyalanmış uçucuyu işaretlemek yerine 'Uçucu Yazma'yı kullanabilir miyim?
class LazyInit<T> where T : class
{
private object m_value;
private object m_sync = new object();
private Func<T> m_factory;
public LazyInit(Func<T> factory) { m_factory = factory; }
public T value
{
get
{
if (m_value == null)
{
lock (m_sync)
{
if (m_value == null)
{
Thread.VolatileWrite(ref m_value, m_factory());
}
}
}
return (T)m_value;
}
}
}
İlgili bir soru kitabı
class LazylnitRelaxedRef<T> where T : class
{
private volatile T m_value;
private Func<T> m_factory;
public LazylnitRelaxedRef(Func<T> factory) { m_factory = factory; }
public T Value
{
get
{
if (m_value == null)
Interlocked.CompareExchange(ref m_value, m_factory(), null);
return m_value;
}
}
}
den İçten kilitli sürümü yana olduğunu (Bu kod Tek bildiğim yerine uçucu yazma kullanabilirsiniz eğer emin olmak, gösteri için biraz garip görünüyor) ECMA-CLI, 'Kilitli işlemin örtülü edinme/serbest bırakma işlemlerini gerçekleştirmesini' şart koşar, bu durumda hala uçucuya ihtiyacımız var mı?
ECMA bellek modeli ve .net 2 bellek modeli arasında önemli bir fark vardır. – CodesInChaos
Neden çift kilitleme kilitlemesi yapmalısınız? Başvurunuzda bir kilit alma ile bir performans sorunu gözlemlediniz mi? –
@CodeInChaos, lütfen "önemli farkın" ne olduğunu açıklayın. – Amy