Esta pregunta se relaciona con colecciones de Java, específicamente Hashtable y Vector, pero también pueden aplicarse en cualquier otro lugar.Programación de interfaces y colecciones sincronizadas
He leído en muchos lugares qué tan bueno es programar interfaces y estoy de acuerdo 100%. La capacidad de programar a una interfaz de lista, por ejemplo, sin tener en cuenta la implementación subyacente es sin duda útil para desacoplar y probar. Con colecciones, puedo ver cómo una ArrayList y una LinkedList son aplicables bajo diferentes circunstancias, dadas las diferencias con respecto a la estructura interna de almacenamiento, los tiempos de acceso aleatorio, etc. Sin embargo, estas dos implementaciones pueden usarse bajo la misma interfaz ... que es genial.
Lo que no puedo ubicar es cómo ciertas implementaciones sincronizadas (en particular, Hashtable y Vector) se ajustan a estas interfaces. Para mí, no parecen ajustarse al modelo. La mayoría de las implementaciones de estructura de datos subyacentes parecen variar en la forma en que se almacenan los datos (LinkedList, Array, árbol ordenado, etc.), mientras que la sincronización trata las condiciones (condiciones de bloqueo) bajo las cuales se puede acceder a los datos. Veamos un ejemplo donde un método devuelve una colección Mapa:
public Map<String, String> getSomeData();
Vamos a suponer que la aplicación no se preocupa en absoluto con la concurrencia. En este caso, operamos en cualquier implementación que regrese el método a través de la interfaz ... Todo el mundo está contento. El mundo es estable.
Sin embargo, ¿qué pasa si la aplicación ahora requiere atención en el frente de concurrencia? Ahora no podemos operar sin tener en cuenta la implementación subyacente: Hashtable estaría bien, pero otras implementaciones deben ser atendidas. Consideremos 3 escenarios:
1) Haga cumplir la sincronización utilizando bloques de sincronización, etc. al agregar/eliminar con la colección. Sin embargo, ¿no sería esto exagerado en caso de que se devuelva una implementación sincronizada (Hashtable)?
2) Cambie la firma del método para devolver Hashtable. Esto, sin embargo, nos vincula fuertemente a la implementación de Hashtable, y como resultado, las ventajas de programar en una interfaz se tiran por la ventana.
3) Haga uso del paquete concurrente y cambie la firma del método para devolver una implementación de la interfaz ConcurrentMap. Para mí, esto parece ser el camino a seguir.
Básicamente, parece que ciertas implementaciones sincronizadas son un poco inadaptadas dentro del marco de colecciones porque, al programar interfaces, el problema de sincronización casi obliga a pensar en la implementación subyacente.
¿Me falta completamente el punto aquí?
Gracias.
Creo que la clave es que añadir unas pocas palabras clave "sincronizadas" aquí o allá no hace que su programa sea seguro para subprocesos. Incluso con colecciones 'java.util.concurrent', desea mantenerlas como detalles privados de implementación. –