Sürüm 9'da Java SE'ye eklenen yeni bir sınıfın SubmissionPublisher
( Java SE 10'daki kaynak kodu, OpenJDK | docs ) nasıl uygulandığını anlamaya çalışırken , daha VarHandle
önce bilmediğim birkaç API çağrısına rastladım :
fullFence
, acquireFence
, releaseFence
, loadLoadFence
Ve storeStoreFence
.
Biraz araştırma yaptıktan sonra, özellikle bellek bariyerleri / çitler kavramı hakkında (daha önce duymuştum, evet; ama onları hiç kullanmadılar, bu yüzden anlamlarına çok aşina değildim), bence ne için olduklarına dair temel bir anlayışa sahibim . Bununla birlikte, sorularım bir yanlış anlamadan kaynaklanabileceğinden, ilk etapta doğru yaptığımdan emin olmak istiyorum:
Bellek engelleri okuma ve yazma işlemleriyle ilgili kısıtlamaları yeniden sıralamaktadır.
Bellek engelleri iki ana kategoriye ayrılabilir: okuma veya yazma ya da her ikisi için sınırlama koymalarına bağlı olarak tek yönlü ve çift yönlü bellek engelleri.
C ++ çeşitli bellek engellerini destekler , ancak bunlar tarafından sağlananlarla eşleşmez
VarHandle
. Bununla birlikte, bazı bellek bariyerleri , karşılık gelen C ++ bellek bariyerleri ile uyumlu olan sipariş efektleriVarHandle
sağlar .#fullFence
ile uyumluatomic_thread_fence(memory_order_seq_cst)
#acquireFence
ile uyumluatomic_thread_fence(memory_order_acquire)
#releaseFence
ile uyumluatomic_thread_fence(memory_order_release)
#loadLoadFence
ve#storeStoreFence
uyumlu C ++ karşı parçası bulunmaz
Anlambilim, ayrıntılar söz konusu olduğunda açıkça farklılık gösterdiğinden, uyumlu kelime burada gerçekten önemli görünüyor. Örneğin, tüm C ++ engelleri çift yönlüdür, oysa Java engelleri (zorunlu olarak) değildir.
- Çoğu bellek engelinin senkronizasyon etkileri de vardır. Bunlar özellikle diğer bariyerlerde kullanılan bariyer tipine ve önceden yürütülen bariyer talimatlarına bağlıdır. Bir bariyer talimatının sahip olduğu tüm çıkarımlar donanıma özgü olduğundan, daha yüksek seviye (C ++) bariyerlere sadık kalacağım. Örneğin, C ++ 'da, bir ayırma bariyeri komutundan önce yapılan değişiklikler, bir edinme bariyeri talimatını yürüten bir iş parçacığı tarafından görülebilir .
Varsayımlarım doğru mu? Öyleyse, ortaya çıkan sorularım:
Mevcut bellek engelleri
VarHandle
herhangi bir bellek senkronizasyonuna neden oluyor mu?Bellek senkronizasyonuna neden olup olmadıklarına bakılmaksızın, Java'da yeniden sıralama kısıtlamaları ne işe yarayabilir? Java Bellek Modeli, uçucu alanlar, kilitler veya
VarHandle
benzeri#compareAndSet
işlemler söz konusu olduğunda siparişle ilgili çok güçlü garantiler vermektedir .
Bir örnek arıyorsanız: Yukarıda belirtilen BufferedSubscription
, bir iç sınıf SubmissionPublisher
(yukarıda bağlantılı kaynak), 1079 satırında tam bir çit oluşturdu (işlev growAndAdd
; bağlantılı web sitesi parça tanımlayıcılarını desteklemediğinden, sadece CTRL + F ). Ancak, bunun için ne olduğu benim için net değil.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
.