Форум
Java
Тема
Как правильно задавать вопросы
B
I
abc
U
X
3
X
3
H1
H2
H3
H4
H5
H6
Asm
C/C++
C#
Erlang
Haskell
IDL
Java
Lisp
MSIL
Nemerle
ObjC
OCaml
Pascal
Perl
PHP
Prolog
Python
Ruby
Rust
SQL
VB
Здравствуйте, vsb, Вы писали: vsb>В общем, если кому надо, накидал такой код, вроде должен работать. Поискал альтернативы, по сути примерно так все делают, для оптимизации производительности можно держать не один глобальный лок на map, а список (выбирать по хешу ключа), но тогда надо вместо HashMap ConcurrentHashMap использовать. vsb>[java] vsb>import java.util.HashMap; vsb>import java.util.Map; vsb>import java.util.concurrent.locks.Lock; vsb>import java.util.concurrent.locks.ReentrantLock; vsb>class LockMap { vsb> interface Unlockable { vsb> void unlock(); vsb> } vsb> private final Lock locksLock = new ReentrantLock(); vsb> private final Map<Object, ReferenceCountingLock> locks = new HashMap<Object, ReferenceCountingLock>(); vsb> Unlockable lock(Object key) { vsb> boolean lockSuccessful = false; vsb> ReferenceCountingLock rcl = acquire(key); vsb> try { vsb> Unlocker unlocker = new Unlocker(key, rcl); vsb> rcl.lock.lock(); vsb> lockSuccessful = true; vsb> return unlocker; vsb> } finally { vsb> if (!lockSuccessful) { vsb> release(key, rcl); vsb> } vsb> } vsb> } vsb> private ReferenceCountingLock acquire(Object key) { vsb> locksLock.lock(); vsb> try { vsb> ReferenceCountingLock rcl = locks.get(key); vsb> if (rcl == null) { vsb> rcl = new ReferenceCountingLock(); vsb> locks.put(key, rcl); vsb> } vsb> rcl.count++; vsb> return rcl; vsb> } finally { vsb> locksLock.unlock(); vsb> } vsb> } vsb> private void release(Object key, ReferenceCountingLock rcl) { vsb> locksLock.lock(); vsb> try { vsb> rcl.count--; vsb> if (rcl.count == 0) { vsb> ReferenceCountingLock oldRCL = locks.remove(key); vsb> if (rcl != oldRCL) { vsb> throw new IllegalStateException(); vsb> } vsb> } vsb> } finally { vsb> locksLock.unlock(); vsb> } vsb> } vsb> private static class ReferenceCountingLock { vsb> private int count; vsb> private final Lock lock = new ReentrantLock(); vsb> } vsb> private class Unlocker implements Unlockable { vsb> private final Object key; vsb> private final ReferenceCountingLock rcl; vsb> private Unlocker(Object key, ReferenceCountingLock rcl) { vsb> this.key = key; vsb> this.rcl = rcl; vsb> } vsb> @Override vsb> public void unlock() { vsb> try { vsb> rcl.lock.unlock(); vsb> } finally { vsb> release(key, rcl); vsb> } vsb> } vsb> } vsb>} vsb>[/java] vsb>Использовать так же, как обычные локи: vsb>[code=java] vsb> Unlockable lock = lockMap.lock(key); vsb> try { vsb> ... vsb> } finally { vsb> lock.unlock(); vsb> } vsb>[/code]
Теги:
Введите теги разделенные пробелами. Обрамляйте в кавычки словосочетания с пробелами внутри, например:
"Visual Studio" .NET
Имя, пароль:
Загрузить
Нравится наш сайт?
Помогите его развитию!
Отключить смайлики
Получать ответы по e-mail
Проверить правописание
Параметры проверки …