ConcurrentHashMap ve Collections.synchronizedMap (Harita) arasındaki fark nedir?


607

Aynı anda birkaç iş parçacığı tarafından değiştirilecek bir harita var.

Java API'sında üç farklı senkronize Harita uygulaması var gibi görünüyor:

  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap

Anladığım kadarıyla, daha sonra arayüze uyacak şekilde uyarlanmış Hashtableeski bir uygulama (eski Dictionarysınıfı genişletiyor ) Map. Senkronize olsa da , ciddi ölçeklenebilirlik sorunları var gibi görünüyor ve yeni projeler için önerilmez.

Peki ya diğer ikisi? Tarafından döndürülen Haritalar Collections.synchronizedMap(Map)ile ConcurrentHashMaps arasındaki farklar nelerdir ? Hangisi hangi duruma uyuyor?


7
@SmilesinaJar Link şu anda bozuk, işte bu makalenin arşivlenmiş bir kopyası: Neden ConcurrentHashMap Hashtable'dan daha iyi ve bir HashMap kadar iyi
informatik01

2
IBM: ConcurrentHashMap, iplik güvenliğinden ödün vermeden daha yüksek eşzamanlılık sunuyor @ ibm.com/developerworks/java/library/j-jtp08223/…
pramodc84

FYI, Java 6 ConcurrentSkipListMapbaşka bir iş parçacığı için güvenli Mapuygulama olarak getirdi . Listeyi Atla algoritması kullanılarak yük altında yüksek eşzamanlı olacak şekilde tasarlanmıştır .
Basil Bourque

Yanıtlar:


423

İhtiyaçlarınız için kullanın ConcurrentHashMap. Haritanın, birkaç iş parçacığından engellenmesine gerek kalmadan aynı anda değiştirilmesine izin verir. Collections.synchronizedMap(map)(düzgün kullanılırsa) tutarlılığı sağlasa da performansı düşürecek bir engelleme Haritası oluşturur.

Veri tutarlılığını sağlamanız gerekiyorsa ve her bir iş parçacığının haritanın güncel bir görünümüne sahip olması gerekiyorsa, ikinci seçeneği kullanın. Performans kritikse ilkini kullanın ve her bir iş parçacığı haritaya yalnızca veri ekler ve okumalar daha az gerçekleşir.


8
Kaynak koduna bakıldığında, senkronize edilmiş harita yalnızca bir muteks (engelleme) ile yapılan bir uygulama iken ConcurrentHashMap, eşzamanlı erişim ile başa çıkmak için daha karmaşıktır
Vinze

123
Lütfen ConcurrentHashMap öğesinin boş anahtarlara veya değerlere izin vermediğini unutmayın. Yani senkronize edilmiş bir haritanın eşit alternatifleri DEĞİLDİR.
onejigtwojig


5
@AbdullahShaikh Bu makalede ortaya çıkan sorun Java 7'de düzeltildi ve Java 8'de daha fazla iyileştirme yapıldı.
pulse0ne

5
@hengxin: haritanın birden çok sorgusundan veya güncellemesinden oluşan bir işlemi gerçekleştirir gerçekleştirmez veya harita üzerinde yineleme yaparken, tutarlılığı sağlamak için harita üzerinde manuel olarak senkronize etmeniz gerekir. Senkronize haritalar, harita üzerinde yalnızca tek işlemler (yöntem çağrıları) için tutarlılığı garanti eder, bu da gerçek yaşam işlemlerinin çoğu önemsiz olduğundan, her zaman manuel olarak senkronize etmeniz gerekir.
Holger

241
╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║   Property    ║     HashMap       ║    Hashtable      ║  ConcurrentHashMap  ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣ 
║      Null     ║     allowed       ║              not allowed                ║
║  values/keys  ║                   ║                                         ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║ Thread-safety ║                   ║                                         ║
║   features    ║       no          ║                  yes                    ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║     Lock      ║       not         ║ locks the whole   ║ locks the portion   ║        
║  mechanism    ║    applicable     ║       map         ║                     ║ 
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║   Iterator    ║               fail-fast               ║ weakly consistent   ║ 
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝

Kilit mekanizması ile ilgili olarak: Hashtable nesnesini kilitler ise, ConcurrentHashMapkilit sadece kova .


13
Hashtableharitanın bir bölümünü kilitlemiyor. Uygulamaya bakın. synchronizedTemelde hashtableher işlemde bütün kilit olduğu anlamına gelen kilitsiz anahtar kullanmaktadır .
RMachnik

6
SynchronizedMap ne olacak?
Samuel Edwin Ward

3
Collections.syncronizedMap davranışı, destekleme haritası gibidir, ancak tüm yöntemler iş parçacığı için güvenlidir
Sergii Shevchyk

5
Tablo yazdırmak ve her biri 5 $ için satmak;). Good one @shevchyk
realPK

Düzenlendi: İkisi de tamamen iş parçacığı için güvenli değildir. Bu yeni geliştiriciler için biraz yanıltıcı. ConcurrentHashMap'in bile harici veri yarışlarından tamamen güvenli olmadığını anlamak için bkz. İbm.com/developerworks/java/library/j-jtp07233/index.html . (örneğin: 1 iş parçacığı bir değeri kaldırır ve daha sonra başka bir değer olup olmadığını denetlemeye çalışır ve bu değeri koymaya çalışır.
Zombies

142

İçin "ölçeklenebilirlik sorunları" Hashtabletam olarak aynı şekilde bulunur Collections.synchronizedMap(Map)- çok basit senkronizasyon kullanırlar, yani haritaya aynı anda yalnızca bir iş parçacığı erişebilir.

Basit ekler ve aramalarınız olduğunda (son derece yoğun bir şekilde yapmadığınız sürece) bu bir sorun değildir, ancak büyük bir Harita için uzun zaman alabilecek olan tüm Harita üzerinde tekrarlamanız gerektiğinde büyük bir sorun haline gelir. bir iş parçacığı bunu yaparsa, diğerleri bir şey eklemek veya aramak isterse beklemek zorundadır.

ConcurrentHashMapÇok sofistike teknikler kullanır senkronizasyon ihtiyacını azaltır ve senkronizasyon olmadan birden çok iş parçacığı tarafından paralel okuma erişimine izin vermek ve daha da önemlisi, sağlayan Iteratorhiçbir senkronizasyon gerektirir ve hiçbir garanti olsun veya kılan olsa bile Haritası (interation tadil etmek gelinebileceğini yineleme sırasında eklenen öğeler döndürülmez).


4
Şimdi istediğim buydu! :) Senkronize olmayan yineleyici sadece saf tatlılıktır! Bilgi için Thansk! :) (:
Kounavi

Harika cevap ... ama okuyucu iş parçacığı senkronize olmadığından alma iş parçacığı sırasında en son güncellemeleri alamayacağı anlamına gelir.
MrA

@MrA: ConcurrentHashMap hakkında mı soruyorsunuz? Ve "geri alma" ile ne demek istiyorsun?
Michael Borgwardt

4
@Michael Borgwardt for ConcurrentHashmap örneğin. birden fazla iş parçacığı olduğunu varsayalım. bazıları haritayı güncelliyor ve bazıları da aynı haritadan veri alıyor. Bu senaryoda, iş parçacıkları okumaya çalışırken, okuyucu iş parçacığı kilitleri tutmak zorunda olmadığı için güncellenen en son verileri alacakları garanti edilir.
MrA

35

ConcurrentHashMap, kullanabileceğinizde tercih edilir - en azından Java 5 gerektirir.

Birden çok iş parçacığı tarafından kullanıldığında iyi ölçeklenecek şekilde tasarlanmıştır. Bir seferde yalnızca tek bir iş parçacığı Haritaya eriştiğinde performans marjinal olarak daha düşük olabilir, ancak aynı anda birden çok iş parçacığı haritaya eriştiğinde önemli ölçüde daha iyi olabilir.

İyice tavsiye ettiğim mükemmel uygulamada Java Concurrency'dan bir tablo üreten bir blog girişi buldum .

Collections.synchronizedMap, yalnızca bir haritayı TreeMap gibi diğer bazı özelliklerle, belki de bir tür sıralı harita ile sarmanız gerektiğinde gerçekten mantıklıdır.


2
Evet - öyle görünüyor ki yaptığım her cevapta bu kitaptan bahsediyorum!
Bill Michell

@BillMichell bağlantısı kopuk

@Govinda Bağlantıya erişmeden önce javascript'i kapatın. Blog girişi hala orada!
Bill Michell

32

Bu ikisi arasındaki temel fark ConcurrentHashMap, verilerin güncellenen sadece bir kısmını kilitlerken verinin diğer kısmına diğer evreler tarafından erişilebilmesidir. Ancak, Collections.synchronizedMap()güncelleme sırasında tüm verileri kilitler, diğer iş parçacıkları yalnızca kilit bırakıldığında verilere erişebilir. Çok sayıda güncelleme işlemi ve görece az miktarda okuma işlemi varsa, seçmelisiniz ConcurrentHashMap.

Ayrıca bir diğer fark, ConcurrentHashMapHaritadaki öğelerin sırasını HashMapkorumamalarıdır. Verileri depolamakla benzerdir . Eleman siparişinin korunduğuna dair bir garanti yoktur. İken Collections.synchronizedMap()koruyacak Harita elemanları amacıyla geçti. Örneğin, bir geçirirseniz TreeMapiçin ConcurrentHashMap, elementler sipariş ConcurrentHashMapdüzen ile aynı olmayabilir TreeMap, ama Collections.synchronizedMap()koruyacaktır sırayla.

Ayrıca, bir iş parçacığı haritayı güncellerken ve başka bir iş parçacığı haritadan alınan yineleyiciyi geçerken fırlatılmadığını ConcurrentHashMapgaranti edebilir ConcurrentModificationException. Ancak, Collections.synchronizedMap()bu konuda garanti edilmez.

Orada bir mesaj bu iki hem de farklılıkları göstermektedir ConcurrentSkipListMap.


13

Senkronize Harita:

Senkronize Harita da Hashtable'dan çok farklı değildir ve eşzamanlı Java programlarında benzer performans sağlar. Hashtable ve SynchronizedMap arasındaki tek fark, SynchronizedMap'in eski olmamasıdır ve Collections.synchronizedMap () yöntemini kullanarak senkronize edilmiş sürümünü oluşturmak için herhangi bir Map'i sarabilirsiniz.

ConcurrentHashMap:

ConcurrentHashMap sınıfı, standart HashMap'in eşzamanlı bir sürümünü sağlar. Bu, Koleksiyonlar sınıfında sağlanan synthesizedMap işlevselliğindeki bir gelişmedir.

Hashtable ve Synchronized Map'in aksine hiçbir zaman tüm haritayı kilitlemez, bunun yerine haritayı bölümlere ayırır ve bunlar üzerinde kilitleme yapılır. Okuyucu iş parçacığı sayısının yazar iş parçacığı sayısından fazla olması daha iyi performans gösterir.

ConcurrentHashMap varsayılan olarak 16 bölgeye ayrılmıştır ve kilitler uygulanır. Bu varsayılan sayı, bir ConcurrentHashMap örneği başlatılırken ayarlanabilir. Belirli bir segmentteki verileri ayarlarken, o segment için kilit elde edilir. Bu, iki güncellemenin her biri ayrı kovaları etkiliyorsa aynı anda güvenli bir şekilde yürütülebileceği, böylece kilit çekişmesini en aza indiren ve performansı en üst düzeye çıkarabileceğiniz anlamına gelir.

ConcurrentHashMap bir ConcurrentModificationException oluşturmaz

ConcurrentHashMap, bir iş parçacığı üzerinden başka bir iş parçacığı üzerinde yineleme yaparken onu değiştirmek için bir ConcurrentModificationException atmaz

SynchornizedMap ve ConcurrentHashMap arasındaki fark

Collections.synchornizedMap (HashMap), Hashtable'a neredeyse eşdeğer bir koleksiyon döndürür; burada, ConcurrentHashMap durumunda, Map haritasındaki her değişiklik işlemi Harita nesnesine kilitlenirken, eşzamanlılık düzeyine göre tüm haritayı farklı bir bölüme bölerek iş parçacığı güvenliği sağlanır. tüm haritayı kilitlemek yerine yalnızca belirli bir bölümü kilitlemek.

Eşzamanlı HashMap bir null anahtara izin verirken ConcurrentHashMap null anahtarlara veya null değerlere izin vermez.

Benzer bağlantılar

link1

link2

Performans karşılaştırması


12

Her zamanki gibi, eşzamanlılık - genel gider - hız dengesi vardır. Bir karar vermek için uygulamanızın ayrıntılı eşzamanlılık gereksinimlerini dikkate almanız ve ardından kodun yeterince iyi olup olmadığını test etmeniz gerekir.


12

Konumunda ConcurrentHashMap, kilit tüm Harita yerine bir segmente uygulanır. Her bölüm kendi dahili karma tablosunu yönetir. Kilit yalnızca güncelleme işlemleri için uygulanır. Collections.synchronizedMap(Map)haritanın tamamını senkronize eder.



9

Haklısın, HashTableunutabilirsin.

Makaleniz , HashTable ve senkronize sarıcı sınıfı, haritaya erişmek için her seferinde yalnızca bir iş parçacığına izin vererek temel iş parçacığı güvenliği sağlarken, birçok bileşik işleminin hala ek senkronizasyon gerektirdiğinden, bu 'gerçek' iş parçacığı güvenliği değildir. misal:

synchronized (records) {
  Record rec = records.get(id);
  if (rec == null) {
      rec = new Record(id);
      records.put(id, rec);
  }
  return rec;
}

Bununla birlikte, bunun yukarıda gösterildiği gibi tipik bir bloğa sahip bir a ConcurrentHashMapiçin basit bir alternatif olduğunu düşünmeyin . Karmaşıklıklarını daha iyi anlamak için bu makaleyi okuyun .HashMapsynchronized


7

İşte az:

1) ConcurrentHashMap, Haritanın yalnızca bir bölümünü kilitler, ancak SynchronizedMap tüm MAp'ı kilitler.
2) ConcurrentHashMap, SynchronizedMap'e göre daha iyi performansa ve daha fazla ölçeklenebilirliğe sahiptir.
3) Çoklu okuyucu ve Tek yazar durumunda ConcurrentHashMap en iyi seçimdir.

Bu metin ConcurrentHashMap ve Java'daki hashtable arasındaki farktan


7

ConcurrentHashMap ve senkronizeHashmap ve Hashtable kullanarak iş parçacığı güvenliğini sağlayabiliriz. Ancak mimarilerine bakarsanız çok fazla fark var.

  1. Hashmap ve Hashtable

Her ikisi de kilidi nesne düzeyinde tutacaktır. Yani put / get gibi herhangi bir işlem yapmak istiyorsanız, önce kilidi almanız gerekir. Aynı zamanda, diğer iş parçacıklarının herhangi bir işlem yapmasına izin verilmez. Yani bir seferde bu konuda sadece bir iş parçacığı çalışabilir. Yani burada bekleme süresi artacak. ConcurrentHashMap ile karşılaştırıldığında performansın nispeten düşük olduğunu söyleyebiliriz.

  1. ConcurrentHashMap

Kilidi segment seviyesinde tutacaktır. 16 segmenti vardır ve varsayılan olarak eşzamanlılık seviyesini 16 olarak korur. Böylece, aynı anda 16 iş parçacığı ConcurrentHashMap üzerinde çalışabilir. Ayrıca, okuma işlemi kilit gerektirmez. Böylece herhangi bir sayıda iş parçacığı, üzerinde bir alma işlemi gerçekleştirebilir.

Eğer thread1 segment 2'de put operasyonu gerçekleştirmek istiyorsa ve thread2 segment 4 üzerinde put operasyonu yapmak istiyorsa, burada buna izin verilir. 16 iş parçacığının ConcurrentHashMap üzerinde bir kerede güncelleme (put / delete) işlemi yapabileceği anlamına gelir.

Böylece bekleme süresi burada daha az olacaktır. Bu nedenle performans senkronize olandan nispeten daha iyidirHashmap ve Hashtable.


1
1. birden fazla evre aynı bloğu düzenlemeye çalışırsa ne olur? 2. İki iş parçacığı, aynı anda veri yazıyorsa başka bir iş parçacığının aynı bloktan veri okumaya çalışırsa ne olur?
prnjn

6

ConcurrentHashMap

  • Projenizde çok yüksek eşzamanlılığa ihtiyacınız olduğunda ConcurrentHashMap kullanmalısınız.
  • Tüm haritayı senkronize etmeden iş parçacığı için güvenlidir.
  • Yazma bir kilitle yapılırken okumalar çok hızlı olabilir.
  • Nesne düzeyinde kilitleme yoktur.
  • Kilitleme, hashmap kovası seviyesinde çok daha ince bir zerreciktedir.
  • ConcurrentHashMap, bir iş parçacığı üzerinden başka bir iş parçacığı üzerinde yineleme yaparken onu değiştirmek için bir ConcurrentModificationException atmaz.
  • ConcurrentHashMap çok sayıda kilit kullanır.

SynchronizedHashMap

  • Nesne düzeyinde senkronizasyon.
  • Her okuma / yazma işleminin kilit alması gerekir.
  • Tüm koleksiyonu kilitlemek bir performans yüküdür.
  • Bu, esasen tüm haritaya yalnızca bir iş parçacığına erişim sağlar ve diğer tüm iş parçacıklarını engeller.
  • Çekişmeye neden olabilir.
  • SynchronizedHashMap, eşzamanlı modifikasyonda hızlı başarısız olan Iterator öğesini döndürür.

kaynak


4

ConcurrentHashMap, eşzamanlı erişim için optimize edilmiştir.

Erişimler haritanın tamamını kilitlemez, ancak ölçeklenebilirliği artıran daha ayrıntılı bir strateji kullanır. Ayrıca, eşzamanlı erişim için, örneğin eşzamanlı yineleyiciler gibi fonksiyonel geliştirmeler de vardır.


4

Arıza güvenlikli yineleyici olan sağladığı eşzamanlılık özelliği dışında dikkat edilmesi gereken önemli bir özellik var . Geliştiricileri sadece entryset - put / remove üzerinde yineleme sırasında düzenlemek istedikleri için kullandım gördüm . arıza güvenlikli yineleyici sağlamaz , bunun yerine arıza hızlı yineleyici sağlar. başarısız-hızlı yineleyiciler, yineleme sırasında düzenlenemeyen harita boyutunun anlık görüntüsünü kullanır.ConcurrentHashMapConcurrentHashMapCollections.synchronizedMap(Map)


3
  1. Veri Tutarlılığı çok önemliyse - Hashtable veya Collections.synchronizedMap (Harita) kullanın.
  2. Hız / performans çok önemliyse ve Veri Güncelleme tehlikeye giriyorsa - ConcurrentHashMap kullanın.

2

Genel olarak, ConcurrentHashMap'güncellemeleri' kaçırmaya hazır olduğunuzdan emin olmak istiyorsanız
(örn. HashMap'in içeriklerinin basılması, haritanın güncel yazdırılmasını sağlamaz) ve CyclicBarrierprogramlarınız arasında tutarlılığı sağlamak için API'leri kullanın yaşam döngüsü.


1

Collections.synchronizedMap () yöntemi, HashMap'in tüm yöntemlerini senkronize eder ve her yöntemi ortak bir kilit üzerinde kilitlediğinden, bir kerede bir iş parçacığının girebileceği bir veri yapısına etkili bir şekilde azaltır.

ConcurrentHashMap senkronizasyonu biraz farklı yapılır. Ortak bir kilit üzerindeki her yöntemi kilitlemek yerine, ConcurrentHashMap ayrı kovalar için ayrı kilit kullanır, böylece Haritanın sadece bir bölümünü kilitler. Varsayılan olarak 16 kova ve ayrı kovalar için ayrı kilitler vardır. Dolayısıyla, varsayılan eşzamanlılık düzeyi 16'dır. Bu, teorik olarak, belirli bir süre 16 iş parçacığı, hepsi ayrı kovalara gidecekse ConcurrentHashMap'e erişebileceği anlamına gelir.


1

ConcurrentHashMap, eşzamanlılık paketinin bir parçası olarak Java 1.5'te Hashtable'a alternatif olarak sunuldu. ConcurrentHashMap ile, sadece eşzamanlı çok iş parçacıklı ortamda güvenli bir şekilde kullanılabilmesi için değil, aynı zamanda Hashtable ve senkronize haritadan daha iyi performans sağlaması durumunda daha iyi bir seçeneğiniz vardır. ConcurrentHashMap, Haritanın bir bölümünü kilitlediğinden daha iyi performans gösterir. Eşzamanlı okuma işlemlerine izin verir ve aynı zamanda yazma işlemlerini senkronize ederek bütünlüğü korur.

ConcurrentHashMap nasıl uygulanır?

ConcurrentHashMap, Hashtable'ın alternatifi olarak geliştirilmiştir ve Hashtable'ın tüm işlevlerini, eşzamanlılık düzeyi adı verilen ek yeteneklerle desteklemektedir. ConcurrentHashMap, birden fazla okuyucunun blok kullanmadan aynı anda okumasını sağlar. Haritayı farklı bölümlere ayırarak ve güncellemelerde Haritanın yalnızca bir bölümünü engelleyerek mümkün olur. Varsayılan olarak eşzamanlılık düzeyi 16'dır, bu nedenle Harita 16 parçaya gönderilir ve her parça ayrı bir blok tarafından yönetilir. Bu, Haritanın farklı bölümleriyle çalışıyorlarsa 16 iş parçasının Harita ile aynı anda çalışabileceği anlamına gelir. ConcurrentHashMap'ı iplik güvenliği için değil üretken yapar.

ConcurrentHashMap'in bazı önemli özellikleri ile ilgileniyorsanız ve haritanın bu gerçekleştirilmesini ne zaman kullanmanız gerekiyorsa - sadece iyi bir makaleye bağlantı koydum - Java'da ConcurrentHashMap nasıl kullanılır?


0

Önerilenlerin yanı sıra, ilgili kaynak kodunu da göndermek istiyorum SynchronizedMap.

Bir Mapiş parçacığını güvenli hale getirmek için Collections.synchronizedMapifade kullanabilir ve map örneğini parametre olarak girebiliriz.

Uygulanması synchronizedMapin Collectionsaltına gibidir

   public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
        return new SynchronizedMap<>(m);
    }

Gördüğünüz gibi, giriş Mapnesnesi nesne tarafından sarılır SynchronizedMap.
Şimdi SynchronizedMap,

 private static class SynchronizedMap<K,V>
        implements Map<K,V>, Serializable {
        private static final long serialVersionUID = 1978198479659022715L;

        private final Map<K,V> m;     // Backing Map
        final Object      mutex;        // Object on which to synchronize

        SynchronizedMap(Map<K,V> m) {
            this.m = Objects.requireNonNull(m);
            mutex = this;
        }

        SynchronizedMap(Map<K,V> m, Object mutex) {
            this.m = m;
            this.mutex = mutex;
        }

        public int size() {
            synchronized (mutex) {return m.size();}
        }
        public boolean isEmpty() {
            synchronized (mutex) {return m.isEmpty();}
        }
        public boolean containsKey(Object key) {
            synchronized (mutex) {return m.containsKey(key);}
        }
        public boolean containsValue(Object value) {
            synchronized (mutex) {return m.containsValue(value);}
        }
        public V get(Object key) {
            synchronized (mutex) {return m.get(key);}
        }

        public V put(K key, V value) {
            synchronized (mutex) {return m.put(key, value);}
        }
        public V remove(Object key) {
            synchronized (mutex) {return m.remove(key);}
        }
        public void putAll(Map<? extends K, ? extends V> map) {
            synchronized (mutex) {m.putAll(map);}
        }
        public void clear() {
            synchronized (mutex) {m.clear();}
        }

        private transient Set<K> keySet;
        private transient Set<Map.Entry<K,V>> entrySet;
        private transient Collection<V> values;

        public Set<K> keySet() {
            synchronized (mutex) {
                if (keySet==null)
                    keySet = new SynchronizedSet<>(m.keySet(), mutex);
                return keySet;
            }
        }

        public Set<Map.Entry<K,V>> entrySet() {
            synchronized (mutex) {
                if (entrySet==null)
                    entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
                return entrySet;
            }
        }

        public Collection<V> values() {
            synchronized (mutex) {
                if (values==null)
                    values = new SynchronizedCollection<>(m.values(), mutex);
                return values;
            }
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            synchronized (mutex) {return m.equals(o);}
        }
        public int hashCode() {
            synchronized (mutex) {return m.hashCode();}
        }
        public String toString() {
            synchronized (mutex) {return m.toString();}
        }

        // Override default methods in Map
        @Override
        public V getOrDefault(Object k, V defaultValue) {
            synchronized (mutex) {return m.getOrDefault(k, defaultValue);}
        }
        @Override
        public void forEach(BiConsumer<? super K, ? super V> action) {
            synchronized (mutex) {m.forEach(action);}
        }
        @Override
        public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
            synchronized (mutex) {m.replaceAll(function);}
        }
        @Override
        public V putIfAbsent(K key, V value) {
            synchronized (mutex) {return m.putIfAbsent(key, value);}
        }
        @Override
        public boolean remove(Object key, Object value) {
            synchronized (mutex) {return m.remove(key, value);}
        }
        @Override
        public boolean replace(K key, V oldValue, V newValue) {
            synchronized (mutex) {return m.replace(key, oldValue, newValue);}
        }
        @Override
        public V replace(K key, V value) {
            synchronized (mutex) {return m.replace(key, value);}
        }
        @Override
        public V computeIfAbsent(K key,
                Function<? super K, ? extends V> mappingFunction) {
            synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
        }
        @Override
        public V computeIfPresent(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
        }
        @Override
        public V compute(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            synchronized (mutex) {return m.compute(key, remappingFunction);}
        }
        @Override
        public V merge(K key, V value,
                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
            synchronized (mutex) {return m.merge(key, value, remappingFunction);}
        }

        private void writeObject(ObjectOutputStream s) throws IOException {
            synchronized (mutex) {s.defaultWriteObject();}
        }
    }

Neler SynchronizedMap, giriş Mapnesnesinin birincil yöntemine tek bir kilit eklemek olarak özetlenebilir . Kilit tarafından korunan tüm yöntemlere aynı anda birden çok iş parçacığı tarafından erişilemez. Gibi araçları normal işlemler bu putve gettüm veriler için, aynı zamanda, tek bir iplik ile yürütülebilir Mapnesne.

MapNesne iş parçacığını şimdi güvenli hale getirir, ancak bazı senaryolarda performans bir sorun haline gelebilir.

Uygulamada ConcurrentMapçok daha karmaşıktır, ayrıntılar için daha iyi bir HashMap Oluşturmaya başvurabiliriz . Özetle, hem iş parçacığı güvenli hem de performans dikkate alınarak uygulanır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.