Достаточно ли безопасен поток в точке входа синхронизированного метода Java?

У меня есть класс Singleton, обрабатывающий вид кэша с различными объектами в Hashmap. (Формат ключа напрямую связан с типом объекта, хранящегося на карте - следовательно, карта имеет)

На карте возможны три различных действия: добавить, получить, удалить.

Я обеспечил доступ к карте с помощью метода публичной точки входа (без интенсивного доступа):

public synchronized Object doAction(String actionType, String key, Object data){
  Object myObj = null;
  if (actionType.equalsIgnorecase("ADD"){
    addDataToMyMap(key,data);
  } else if (actionType.equalsIgnorecase("GET"){
    myObj = getDataFromMyMap(key);
  } else if (actionType.equalsIgnorecase("REM"){  
    removeDataFromMyMap(key);      
  }
  return myObj;
}

Заметки:

Карта является частной. Методы addDataToMyMap(), getDataFromMyMap() и removeDataFromMyMap() являются закрытыми. Только метод точки входа является общедоступным, и ничего кроме статического getInstance() самого класса.

Вы подтверждаете, что это потокобезопасный для одновременного доступа к карте, поскольку нет другого способа использовать карту, кроме как с помощью этого метода?

Если это безопасная карта, я думаю, этот принцип может быть применен к любому другому виду общего ресурса.

Заранее большое спасибо за ваши ответы.

Дэвид

8 ответов

Решение

Мне нужно будет увидеть вашу реализацию ваших методов, но этого может быть достаточно. НО я бы порекомендовал вам использовать Map из API Collection из java, тогда вам не нужно будет синхронизировать ваш метод, если вы не поделились каким-либо другим экземпляром.

Прочитайте это: http://www.java-examples.com/get-synchronized-map-java-hashmap-example

Да, ваш класс будет потокобезопасным, если единственной точкой входа является doAction.

Это совершенно безопасно. До тех пор, пока все потоки обращаются к нему с помощью общей блокировки, которая в данном случае является объектом, она является поточно-ориентированной. (Другие ответы могут быть более производительными, но ваша реализация безопасна.)

Если твой cache класс имеет личное HashMap и у вас есть три метода, и все public synchronized и не static и если у вас нет другого public переменная экземпляра, то я думаю, что ваш кэш thread-safe,

Лучше разместить свой код.

Как это трудно определить, является ли код потокобезопасным. Важная информация, отсутствующая в вашем примере:

  1. Являются ли методы публичными
  2. Синхронизированы ли методы
  3. Это карта доступна только через методы

Я бы посоветовал вам изучить синхронизацию, чтобы понять проблемы и решить их. Изучение класса ConcurrentHashMap даст дополнительную информацию о вашей проблеме.

Вы должны использовать ConcurrentHashMap. Он предлагает лучшую пропускную способность, чем синхронизированный doAction, и лучшую безопасность потоков, чем Collections.synchronizedMap().

Это зависит от вашего кода. Как кто-то еще сказал, вы можете использовать Collections.synchronizedMap. Однако это синхронизирует только отдельные вызовы методов на карте. Так что если:

map.get(key);
map.put(key,value);

Выполняются одновременно в двух разных потоках, один будет блокироваться, пока другой не выйдет. Однако, если ваш критический раздел больше, чем один вызов на карту:

SomeExpensiveObject value = map.get(key);
if (value == null) {
   value = new SomeExpensiveObject();
   map.put(key,value);
}

Теперь давайте предположим, что ключа нет. Первый поток выполняется и возвращает нулевое значение. Планировщик возвращает этот поток и запускает поток 2, который также возвращает нулевое значение. Он создает новый объект и помещает его в карту. Затем поток 1 возобновляет работу и делает то же самое, поскольку он все еще имеет нулевое значение.

Это где вы хотите больший блок синхронизации вокруг вашего критического раздела

SomeExpensiveObject value = null;

synchronized (map) {
  value = map.get(key);
  if (value == null) {
     value = new SomeExpensiveObject();
     map.put(key,value);
  }
}

Вы можете использовать Collections.synchronizedMap для синхронизации доступа к Map,

Другие вопросы по тегам