Возможный дубликат:
Каков наилучший способ увеличить количество блокировок в java.
Предположим, что я хочу заблокировать на основе целочисленного значения id. В этом случае есть функция, которая извлекает значение из кеша и делает довольно дорогое извлечение/сохранение в кеш, если значение не существует.
Существующий код не синхронизирован и может запускать несколько операций извлечения/хранения:
//psuedocode
public Page getPage (Integer id){
Page p = cache.get(id);
if (p==null)
{
p=getFromDataBase(id);
cache.store(p);
}
}
То, что я хотел бы сделать, это синхронизировать извлечение по идентификатору, например.
if (p==null)
{
synchronized (id)
{
..retrieve, store
}
}
К сожалению, это не сработает, потому что два отдельных вызова могут иметь одно и то же значение id целого числа, но другой объект Integer, поэтому они не будут использовать блокировку, и синхронизация не произойдет.
Есть ли простой способ убедиться, что у вас есть один и тот же экземпляр Integer? Например, будет ли это работать:
syncrhonized (Integer.valueOf(id.intValue())){
javadoc для Integer.valueOf(), похоже, подразумевает, что вы, вероятно, получите тот же экземпляр, но это не похоже на гарантию:
Возвращает экземпляр Integer представляющий заданное значение int. Если новый экземпляр Integer не является требуется, этот метод должен в целом использовать в предпочтении конструктор Integer (int), так как это метод, вероятно, даст значительно лучшее пространство и время производительность при кешировании запрошенные значения.
Итак, любые предложения о том, как получить экземпляр Integer, который гарантированно будет таким же, кроме более сложных решений, таких как сохранение объектов WeakHashMap Lock, привязанных к int? (ничего страшного в этом, кажется, что должен быть очевидный однострочный, чем мне не хватает).