2014-11-07 7 views
6

Heute habe ich eine Frage in meinem Interview gestellt. Die Frage ist, dass Collections.synchronizedMap() verwendet wird, um die Karte zu synchronisieren, die standardmäßig nicht threadsicher sind wie hashmap. Seine Frage ist, aber wir können jede Art von Karte innerhalb dieser Methode übergeben. Also was ist der Effekt, wenn wir eine Hashtabelle innerhalb dieser Methode übergeben, weil Hashtabelle standardmäßig synchronisiert ist.Was passiert, wenn wir die Hashtable in Collections.synchronizedMap() übergeben

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

Die synchronizedMap() Methode nicht zwischen den verschiedenen Arten von Map s bestanden darin unterscheiden:

Antwort

0

Wenn Sie den Code in der SynchronizedCollection sehen.Die Methoden werden den Anruf an die zugrunde liegende Auflistung delegieren aber das Hinzufügen synchronisierten Block an der Spitze des Anruf so etwas wie diese

public int size() { 
synchronized (mutex) {return c.size();} 
} 

Die Umsetzung der Größe wie diese

in HashTable Klasse sieht
public synchronized int size() { 
    return count; 
} 

Also, wenn Übergeben Sie HashTable an SynchronizedCollection, muss der Thread, der auf SynchronizedCollection zugreift, die Sperren auf 2 Ebenen einmal für synchronisierten Block und einen anderen für synchronisierte Methode nehmen. Wenn andere Threads das HashTable-Objekt direkt verwenden, können sie die Threads mithilfe der SynchronizedCollection blockieren, selbst wenn der Thread die Sperre auf SynchronizedCollection erhalten hat.

+0

Kopie von Natixs Antwort? – user219882

+1

Ich schrieb die Antwort parallel zu ihm Ich denke, ich bin mir nicht sicher, warum es unten bestellt ist, und ich habe einen Grund gegeben, warum es nicht tun. –

1

Es wird in eine SynchronizedMap, von java.util.Collections erhalten gewickelt.

2

Sie würden zwei Synchronisationsebene haben: eine auf der Ebene der synchronisierten Karte selbst, durch ein Mutex-Objekt implementiert, und eine auf der Ebene der umhüllte Instanz:

public boolean isEmpty() { 
    // first level synchronization 
    synchronized(mutex) { 
     // second level synchronization if c is a Hashtable 
     return c.isEmpty(); 
    } 
} 

Die zusätzliche Synchronisation nicht benötigt wird, und kann zu einer geringeren Leistung führen.

Ein weiterer Effekt ist, dass Sie nicht API von Hashtable wie Hashtable#elements verwenden können, da die umschlossene Sammlung jetzt streng eine Map Instanz ist.

3

Das Verhalten der Zuordnung wird gleich sein, aber die Leistung wird beeinträchtigt, da jede Methode zwei Synchronisierungssperren anstelle von einer erhält.

Betrachten Sie zum Beispiel den Aufruf der Methode size() auf der resultierenden Karte. Die Umsetzung in der Collections.SynchronizedMap Klasse sieht wie folgt aus:

public int size() { 
    synchronized(mutex) {return m.size();} // first lock 
} 

... wo m.size() die Implementierung ruft in Hashtable:

public synchronized int size() { // second lock 
    return count; 
} 

Das erste Sperrobjekt ist das mutex Feld in SynchronizedMap. Die zweite Sperre ist implizit - die Hashtable-Instanz selbst.

0

"Seine Frage ist, aber wir können jede Art von Karte innerhalb dieser Methode übergeben."

Die Antwort ist ja, weil der Konstruktor von SynchronizedMap jede Map in seiner Signatur akzeptiert.

„Also, was ist der Effekt, wenn wir eine Hash-Tabelle innerhalb dieser Methode übergeben, da Hash-Tabelle ist standardmäßig synchronisiert“

Die Antwort lautet: Wir zeigen Unwissenheit der ConcurrentHashMap die meisten wird wahrscheinlich das Werkzeug statt zu sein verwendet einer blockierenden Implementierung.

Verwandte Themen