2009-11-21 19 views
16

Hashtable gibi koleksiyonların senkronize olduğunu anlıyorum, ancak birisi bana 'un nasıl çalıştığını ve'un nasıl çalıştığını ve eşzamanlı çağrılar için hangi noktaya erişimin kısıtlandığını anlayabilirim? Örneğin, bu gibi bazı iteratörler diyelim:Yineleyiciler kullanıldığında koleksiyonların senkronizasyonunu açıklar mısınız?

Hashtable<Integer,Integer> map = new Hashtable<Integer,Integer>(); 

void dosomething1(){ 
    for (Iterator<Map.Entry<Integer,Integer>> i = map.entrySet().iterator(); i.hasNext();){ 
     // do something 
    } 
} 
void dosomething2(){ 
    for (Iterator<Map.Entry<Integer,Integer>> i = map.entrySet().iterator(); i.hasNext();){ 
     // do something 
     // and remove it 
     i.remove(); 
    } 
} 
void putsomething(int a, int b){ 
    map.put(a,b); 
} 
void removesomething(int a){ 
    map.remove(a); 
} 
var clear(){ 
    map = new Hashtable<Integer,Integer>(); 
} 

farklı parçacığı rastgele bu işlevleri çağıran benimle herhangi tuzaklar varsa birisi açıklayabilir misiniz? Yineleyici, özellikle, senkronizasyon gerektirecek gibi, özellikle inputSet() kullanırken, senkronizasyonunu nasıl yapar? Döngülerden biri devam ederken clear() çağrılırsa ne olur? Removeesomething1(), henüz bir eşzamanlı döngü tarafından işlenmemiş bir öğeyi dosomething1()?

Yardımlarınız için teşekkürler! Eğer senkronize sarmalayıcıların birini (Collections.synchronizedMap(...)) kullanıyor olsalar bile Java koleksiyonları üzerinde

cevap

34

Yineleme, iş parçacığı güvenli değil:

Bitti yineleme kullanıcı el döndü harita üzerinde senkronize zorunludur onun toplama görünümleri herhangi:

Map m = Collections.synchronizedMap(new HashMap()); 
... 
Set s = m.keySet(); // Needn't be in synchronized block 
... 
synchronized(m) { // Synchronizing on m, not s! 
    Iterator i = s.iterator(); // Must be in synchronized block 
    while (i.hasNext()) 
     foo(i.next()); 
} 

Java Collection Framework docs

orijinal koleksiyon olmak

public int size() { 
    synchronized(this) { 
     return collection.size(); 
    } 
} 

: sarıcı sınıflar kendi monitör olarak sarıcı koleksiyonu kullanmak synchronized bloklar, onları çevreleyen olarak senkronize koleksiyonlarına 0

Diğer çağrılar, güvenlidir. Bu, yineleme öğeleri haricinde, bir koleksiyon/harita tarafından gösterilen tüm yöntemler için çalışır.

Bir haritanın anahtar seti, aynı şekilde senkronize edilir: senkronize edilmiş sarıcı, orijinal anahtar kümesini hiç döndürmez. Bunun yerine, koleksiyonun orijinal anahtar kümesinin özel bir eşzamanlı sarıcısını döndürür. Aynısı giriş seti ve değer kümesi için de geçerlidir.

+0

Yanıtı düzelttim: kullanılan ekran aslında orijinal olan değil sarmalayıcı koleksiyonudur. – Dirk

+0

Bu süper yararlı ve çok iyi sundu. Açıkça açıklayan bir kaynak bulmakta zorlanıyordum, bu yüzden çok teşekkürler! – DivideByHero

+0

"Java'daki koleksiyonlar üzerinde yineleme, senkronize edilmiş sarmalayıcılardan birini kullanıyor olsanız bile, iş parçacığı güvenli değildir." O_o korkunç – rkarajan

İlgili konular