Имеется ситуация, в которой оказалось удобно использовать код вида
synchronized (key.toString().intern()) {
...
}
но многие пишут, что так не стоит делать, это засорение intern-пула, это теоретический дедлок, если в другом месте случайно по той же строке будет синхронизация и тд. Вопрос — чем заменить этот код? Пока написал как-то так (Java 7):
ConcurrentMap<Key, Object> locks = new ConcurrentHashMap<>();
...
Object lock = locks.get(key);
if (lock == null) {
Object newLock = new Object();
Object existingLock = locks.putIfAbsent(key, newLock);
lock = existingLock == null ? newLock : existingLock;
}
synchronized (lock) {
...
}
но как-то это всё сложно выглядит. Не упускаю ли я какой-то готовый примитив синхронизации? Помимо прочего тут ещё и locks будет расти, в моём случае я её чищу сразу после synchronized, потому что у меня этот блок выполняется один раз, но в общем случае так нельзя делать, я сходу даже не соображу, как правильно это написать для общего случая.