Java nasıl çalışır

Konu seç, kod yaz ve içeride ne olduğunu adım adım gör.

Memory

Collection'lar

Concurrency

Dil ve JVM

Konular

ConcurrentHashMap nasıl çalışır

HashMap neden yetmez?

HashMap thread-safe değildir: aynı anda yazan thread'ler Node kaybedebilir, resize'ı bozabilir.

Hashtable her method'u tek lock'a bağlar: thread'ler farklı bucket'larla çalışsa da birbirini bekler.

ConcurrentHashMap lock'u bucket seviyesine indirir: farklı bucket'lar genellikle birbirini engellemez. Java 7'deki Segment yapısı Java 8'de kaldırıldı.

Boş bucket: CAS

Bucket boşsa lock almaya gerek yoktur. Thread CAS kullanır: null ise Node'u yaz.

İki thread aynı boş bucket'a yazarsa biri kazanır. Diğerinin CAS'ı başarısız olur ve put yeniden başlar: artık bucket doludur.

Dolu bucket: lock

Bucket doluysa thread ilk Node üzerinde synchronized alır. Lock yalnızca bu bucket içindir.

Aynı bucket'a yazan thread bekler, başka bucket'a yazan beklemez. Hashtable'dan temel fark budur.

Neden null olmaz?

HashMap'te get null döndürünce containsKey ile bakabilirsin: key mi yok, yoksa value mu null?

Çok thread'de bu iki çağrı arasında map değişebilir, bu yüzden cevap güvenilir olmaz. Bu karışıklık olmasın diye ConcurrentHashMap null key ve null value kabul etmez.

Solda put(null, 1) düğmesine bas.

Resize: biraz erken ve birlikte

Burada 11 key var. Solda k12 için put bas: table 12. key'de büyür. HashMap ise 13. key'de büyür.

Taşıma sırasında taşınan bucket'a ForwardingNode konur. get onun üzerinden yeni table'a geçer, put yapan thread ise taşımaya yardım eder.

Yer değiştiren Node'lar sağda işaretlenir. Node'lar bazen zincirde ters sıraya düşer, bu da JDK koduyla aynıdır.

Atomic işlemler ve size

Her çağrı tek başına güvenlidir, ama get, sonra put birlikte atomic değildir: arada başka thread yazabilir.

Bunun için merge, compute, computeIfAbsent ve putIfAbsent vardır.

size() yaklaşık da olabilir: sayaç baseCount ve CounterCell'lere bölünmüştür. Thread'ler yazarken sonuç kesin olmayabilir.