La investigación principal en este artículo es el contenido relevante del uso de ConcurrentMap.putIfAbsent(key,value) , como sigue.
Este tipo de escenario a menudo se encuentra en los negocios. Se mantiene un mapa concurrente concurrente a nivel mundial. Cada clave del mapa corresponde a un objeto, y este objeto debe crearse solo una vez. Si el valor correspondiente a la clave en el mapa no existe, se creará, de lo contrario se devolverá directamente.
Veamos primero el código:
Public static locale getInstance (lenguaje de cadena, string country, string variant) {// ... clave de cadena = some_string; Locale locale = map.get (clave); if (locale == null) {locale = new locale (idioma, país, variante); map.put (clave, localidad); } RETURN LOCALE; } Lo que este código debe hacer es:
Esperamos que cada vez que se llame al método GetInstance, debemos asegurarnos de que la misma clave devuelva la misma referencia de objeto local. ¿Puede este código lograr este requisito?
La respuesta es: los requisitos se pueden cumplir en un entorno único, pero habrá problemas de seguridad de hilos en un entorno múltiple, es decir, no se puede garantizar que la misma clave en concurrencia devolverá la misma referencia de objeto local.
Esto se debe a que hay un hábito en el código anterior llamado operación put if-ausente [1], y esta operación tiene una condición de carrera:
if (locale == null) {locale = new locale (idioma, país, variante); map.put (clave, localidad); } Porque después de que un hilo haya terminado de juzgar locales == nulo, es cierto poner valor en el mapa. Otros hilos pueden haber realizado operaciones en el mapa. Al volver a realizar operaciones, el objeto local correspondiente a la misma clave se sobrescribe, y finalmente la referencia local de la misma clave devuelta por el método GetInstance será inconsistente. Por lo tanto, la operación PUT-if-ABSENT en el mapa no es segura (seguro de hilo).
Para resolver este problema, Java 5.0 introdujo la interfaz concurrentMAP, donde la operación put if-ausente existe en forma de un método atómico putIfAbsent(K key, V value) . Como Javadoc escribe:
Al agregar un par de valores clave al ConcurrentHashmap, primero determinará si el par de valores clave ya existe.
Revisar el método anterior:
Public static locale getInstance (lenguaje de cadena, string country, string variant) {// ... clave de cadena = some_string; Locale locale = map.get (clave); if (locale == null) {locale = new locale (idioma, país, variante); map.putifabsent (clave, localidad); } RETURN LOCALE; } Este código utiliza la forma concurrente de MAP (concurrentMap, concurrenthashmap), y simplemente usa la declaración map.putIfAbsent(key, locale) . Esto tampoco garantiza que la misma clave devuelva la misma referencia de objeto local.
El error aquí es que el método Putifabsent tiene un valor de retorno, y el valor de retorno es importante.
Por lo tanto, cuando use el método Putifabsent, recuerde juzgar el valor de retorno.
Public static locale getInstance (lenguaje de cadena, string country, string variant) {// ... clave de cadena = some_string; Locale locale = map.get (clave); if (locale == null) {locale = new locale (idioma, país, variante); Locale tmp = map.putifabsent (clave, localidad); if (tmp! = null) {locale = tmp; }} return loce; } import java.util.map; import java.util.concurrent.concurrenthashmap; public class test {public static void main (string [] args) {// prueba currenthashmap.putifabsent () map <long, string> clientMap = nuevo concenthASHHMAP <> (); system.out.println ("clientMapsap Primero "); System.out.println (" ClientMap: " + ClientMap); System.out.println (); // Agregar un nuevo registro en el clientMap vacío.out.out.println (" Agregue un nuevo registro en el clientMap "vacío"); system.out.println ("Agregue un mapas anterior:" + clientMap); long netid = 1234567L; string; string; string; string; string; string; string; string; string; string; string; string; string; string; string; string; string; string dup. clientMap.putifabSent (netid, str1); system.out.println ("Agregue un clientMap anterior:" + clientMap); system.out.println ("ver valor de retorno resultado:" + resultado); system.println (); // repita agregar system.out.println ("repetir el último registro"); system.out.println ("antes de agregar) resultado2 = ClientMap.PutifabSent (NetID, Str1); System.out.println ("Después de agregar ClientMap:" + ClientMap); System.out.println ("Ver resultado del valor de retorno:" + resultado2); System.out.println ();}}}}Lo anterior es todo el contenido de este artículo sobre el ejemplo de uso de concurrentMap.putifabsent (clave, valor) y espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!