Die Hauptforschung in diesem Artikel ist der relevante Inhalt der Verwendung von ConcurrentMap.putIfAbsent(key,value) wie folgt.
Diese Art von Szenario tritt oft im Geschäft an. Eine gleichzeitige Concurrentmap wird weltweit aufrechterhalten. Jeder Schlüssel der Karte entspricht einem Objekt, und dieses Objekt muss nur einmal erstellt werden. Wenn der Wert, der dem Schlüssel in der Karte entspricht, nicht vorhanden ist, wird er erstellt, andernfalls wird er direkt zurückgegeben.
Schauen wir uns zuerst den Code an:
öffentliches statisches Gebietsschema GetInstance (String -Sprache, String Country, String -Variante) {// ... String key = slow_string; Locale Locale = map.get (Schlüssel); if (Locale == NULL) {Locale = New Locale (Sprache, Land, Variante); map.put (Schlüssel, Gebietsschema); } Return Locale; } Was dieser Code tun muss, ist:
Wir gehen davon aus, dass wir jedes Mal, wenn die GetInstance -Methode aufgerufen wird, sicherstellen muss, dass derselbe Schlüssel dieselbe lokale Objektreferenz zurückgibt. Kann dieser Code diese Anforderung erreichen?
Die Antwort lautet: Die Anforderungen können in einer einsthread-Umgebung erfüllt werden. In einer Umgebung mit Multi-Threaden wird jedoch Sicherheitsprobleme auftreten, dh kann nicht garantiert werden, dass der gleiche Schlüssel in der Parallelität dieselbe lokale Objektreferenz zurückgibt.
Dies liegt daran, dass der obige Code, der als Put-IF-Abent-Operation bezeichnet wird, eine Gewohnheit [1] und diese Operation eine Rennbedingung hat:
if (Locale == NULL) {Locale = New Locale (Sprache, Land, Variante); map.put (Schlüssel, Gebietsschema); } Da nach einem Thread das Gebietsschema beurteilt hat == NULL, ist es wahr, Wert in die Karte zu setzen. Andere Threads haben möglicherweise bereits Operationen auf der Karte ausgeführt. Bei erneutem Operationen wird das Gebietsschemasobjekt, das demselben Schlüssel entspricht, überschrieben, und schließlich ist die von der GetInstance -Methode zurückgegebene Gebietsschemasreferenz inkonsistent. Daher ist der Put-IF-Abg-Betrieb auf der Karte nicht sicher (Faden sicher).
Um dieses Problem zu lösen, führte Java 5.0 die ConcurrentMap-Grenzfläche ein, wobei der Put-IF-Abg-Operation in Form einer Atommethode putIfAbsent(K key, V value) vorhanden ist. Wie Javadoc schreibt:
Beim Hinzufügen eines Schlüsselwertpaares zur Concurrenthashmap wird zunächst festgelegt, ob das Schlüsselwertpaar bereits vorhanden ist.
Überarbeiten Sie die obige Methode:
öffentliches statisches Gebietsschema GetInstance (String -Sprache, String Country, String -Variante) {// ... String key = slow_string; Locale Locale = map.get (Schlüssel); if (Locale == NULL) {Locale = New Locale (Sprache, Land, Variante); MAP.PUTIFABSENT (Schlüssel, Gebietsschema); } Return Locale; } Dieser Code verwendet die gleichzeitige Form von MAP (ConcurrentMap, Concurrenthashmap) und einfach die Anweisung map.putIfAbsent(key, locale) . Dies garantiert auch nicht, dass der gleiche Schlüssel dieselbe Referenz des Gebietsschemasobjekts zurückgibt.
Der Fehler hierfür ist, dass die PutifabSent -Methode einen Rückgabewert hat und der Rückgabewert wichtig ist.
Denken Sie daher bei der Verwendung der PutifAbent -Methode daran, den Rückgabewert zu beurteilen.
öffentliches statisches Gebietsschema GetInstance (String -Sprache, String Country, String -Variante) {// ... String key = slow_string; Locale Locale = map.get (Schlüssel); if (Locale == NULL) {Locale = New Locale (Sprache, Land, Variante); Lokalschema TMP = MAP.PUTIFABSENT (Schlüssel, Lokalschema); if (tmp! = null) {locale = tmp; }} Return Locale; } importieren java.util.map; import java.util.concurrent First "); System.out.println (" Clientmap: " + clientmap); System.out.println (); // Fügen Sie einen neuen Datensatz im leeren Clientmap -System hinzu. clientmap.putiFabSent (NetId, Str1); System.out.println ("Vorheriger Clientmap hinzufügen:" + clientmap); System.out.println ("Rückgabe -Wertergebnis anzeigen:" + result); System.out.Out.Outln (). result2 = clientmap.putiFABSent (NetId, Str1); System.out.println ("Nach Hinzufügen von Clientmap:" + clientmap); System.out.println ("Rückgabewert Ergebnis anzeigen Ergebnis:" + result2); System.out.println ();}}Das obige ist der gesamte Inhalt dieses Artikels über das Verwendungsbeispiel von ConcurrentMap.PutiFabSent (Schlüssel, Wert), und ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!