Pregunta ¿Qué sucede cuando pasamos hashtable dentro de Collections.synchronizedMap ()


Hoy hice una pregunta en mi entrevista. La pregunta es que Collections.synchronizedMap () es se utiliza para sincronizar el mapa, que por defecto no es seguro para subprocesos como hashmap. Su pregunta es, pero podemos pasar cualquier tipo de mapa dentro de este método. Entonces, ¿cuál es el efecto cuando pasamos una tabla hash dentro de este método porque hashtable está sincronizado por defecto?


6
2017-11-07 11:29


origen


Respuestas:


Si ves el código en el SynchronizedCollection. Los métodos delegarán la llamada a la colección subyacente pero agregarán el bloque sincronizado en la parte superior de la llamada algo como esto

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

La implementación del tamaño se ve así en HashTable clase

public synchronized int size() {
    return count;
}

Así que, si pasas HashTable a SynchronizedCollection, el hilo accediendo a SynchronizedCollection tendrá que tomar los bloqueos en 2 niveles una vez para el bloque sincronizado y otro para el método sincronizado. Si hay otros subprocesos que usan el objeto HashTable directamente, pueden bloquear los subprocesos utilizando el SynchronizedCollection incluso cuando el hilo consiguió el bloqueo en SynchronizedCollection.


0
2017-11-07 11:53



El comportamiento del mapa será el mismo, pero el rendimiento se verá afectado, ya que cada método adquirirá dos bloqueos de sincronización en lugar de uno.

Por ejemplo, considere llamar al método size() en el mapa resultante. La implementación en el Collections.SynchronizedMap clase se ve así:

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

... dónde, m.size() llama a la implementación en Hashtable:

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

El primer objeto de bloqueo es el mutex campo en SynchronizedMap. El segundo bloqueo es implícito - el Hashtable instancia en sí.


3
2017-11-07 11:42



Tendría dos niveles de sincronización: uno al nivel del mapa sincronizado, implementado por un objeto mutex y otro al nivel de la instancia envuelta:

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

La sincronización adicional no es necesaria y puede llevar a un rendimiento más bajo.

Otro efecto es que no podrás usar API desde Hashtable me gusta Hashtable#elements ya que la colección envuelta es ahora estrictamente una Map ejemplo.


2
2017-11-07 11:38



Se envolverá en un SynchronizedMap, de java.util.Collections:

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

los synchronizedMap() método no distingue entre los tipos de Maps pasó a él.


1
2017-11-07 11:34



"Su pregunta es, pero podemos pasar cualquier tipo de mapa dentro de este método".

La respuesta es sí, porque el constructor de SynchronizedMap acepta cada Map en su firma.

"Entonces, ¿cuál es el efecto cuando pasamos una tabla hash dentro de este método porque hashtable está sincronizado por defecto"

La respuesta es: estamos mostrando ignorancia a la ConcurrentHashMap que es más probable que la herramienta sea utilizada en lugar de una implementación de bloqueo.


0
2017-11-07 11:49