Основным исследованием в этой статье является соответствующее содержание использования ConcurrentMap.putIfAbsent(key,value) , следующим образом.
Этот вид сценария часто встречается в бизнесе. Одновременная параллельная карта поддерживается во всем мире. Каждый ключ карты соответствует объекту, и этот объект должен быть создан только один раз. Если значение, соответствующее ключу на карте, не существует, оно будет создано, в противном случае оно будет возвращено напрямую.
Сначала посмотрим на код:
public static locale getInstance (строковый язык, String Country, String Variant) {// ... String Key = some_string; Locale locale = map.get (key); if (locale == null) {locale = new locale (язык, страна, вариант); map.put (key, locale); } вернуть локаль; } Что должен сделать этот код:
Мы ожидаем, что каждый раз, когда вызывается метод GetInstance, мы должны убедиться, что тот же ключ возвращает одну и ту же ссылку на локальный объект. Может ли этот код достичь этого требования?
Ответ: требования могут быть выполнены в однопоточной среде, но в многопоточной среде будут проблемы с безопасностью потока, то есть нельзя гарантировать, что тот же ключ в параллелизме вернет ту же ссылку на локальный объект.
Это потому, что в приведенном выше коде есть привычка, называемая операцией PUT-if-absent [1], и эта операция имеет условие гонки:
if (locale == null) {locale = new locale (язык, страна, вариант); map.put (key, locale); } Поскольку после того, как поток закончил судить локали == null, верно положить значение на карте. Другие потоки, возможно, уже сделали операции на карте. При выполнении операций снова будет перезагружен объект Locale, соответствующий тому же ключу, и, наконец, ссылка на локали того же ключа, возвращаемого методом GetInstance, будет непоследовательной. Следовательно, операция PUT-if-absent на карте не безопасна (резьба безопасна).
Чтобы решить эту проблему, Java 5.0 представила интерфейс concurrentMap, где в форме атомного метода putIfAbsent(K key, V value) absent. Как пишет Джавадок:
При добавлении пары клавиш в concurrenthashmap сначала определит, существует ли уже пара ключевых значений.
Пересмотрите вышеуказанный метод:
public static locale getInstance (строковый язык, String Country, String Variant) {// ... String Key = some_string; Locale locale = map.get (key); if (locale == null) {locale = new locale (язык, страна, вариант); map.putifabsent (Key, Locale); } вернуть локаль; } В этом коде используется параллельная форма карты (concurrentmap, concurrenthashmap) и просто использует map.putIfAbsent(key, locale) . Это также не гарантирует, что тот же ключ возвращает ту же ссылку на объект локали.
Ошибка здесь заключается в том, что метод Putifabsent имеет возвращаемое значение, и возвращаемое значение важно.
Поэтому при использовании метода Putifabsent не забудьте судить о возвратной стоимости.
public static locale getInstance (строковый язык, String Country, String Variant) {// ... String Key = some_string; Locale locale = map.get (key); if (locale == null) {locale = new locale (язык, страна, вариант); Locale tmp = map.putifabsent (key, locale); if (tmp! = null) {locale = tmp; }} return locale; } Импорт java.util.map; import java.util.concurrent.concurrenthashmap; public class test {public static void main (string [] args) {// test currenthashmap.putifabsent () map <long, string> clientmap = new concurrenthamap <> system.out.printl Первый "); System.out.println (" clientMap: " + clientMap); System.out.println (); // Добавить новую запись в пустую ClientMap System.out.println (" Добавить новую запись в пустую клиенту "); System.out.println (" Добавить предыдущую клиенту: " + clientmap); long netid = 1234567; clientMap.putIfAbsent(netId, str1);System.out.println("Add a previous clientMap: " + clientMap);System.out.println("View return value result: " + result);System.out.println();//Repeat add System.out.println("Repeat the last record");System.out.println("Before add clientMap: " + clientMap);String result2 = clientMap.PutifaBsent (netId, str1); System.out.println ("После добавления clientMap:" + clientMap); System.out.println ("Просмотр return Value Result:" + result2); System.out.println ();}}Выше приведено все содержание этой статьи о примере использования concurrentmap.putifabsent (ключ, ценность), и я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!