Блок потоков на основе ввода функции
Я попал в ситуацию, когда мне нужно синхронизировать функцию на основе ввода. например. Есть функция. func(int a)--- эта функция может вызываться многими потоками. Я хочу заблокировать потоки, если они пытаются вызвать эту функцию с одним и тем же входным целым числом. В противном случае пусть они продолжаются без продолжения. Я написал функцию
HashTable<Integer> check=new Hashtable<Integer>();
func(int a){
Integer lock=check.get(a);
if(lock==null){
check.put(a);
}else{
check.put(a);
}
synchronized(lock){
//do something....
} }
Пожалуйста, дайте мне знать, если это правильно. Также, если есть другое решение, кроме этого. Я пытаюсь выяснить. Если я найду ответ, я опубликую его.
1 ответ
Решение
1) получение блокировки тоже должно быть в синхронизированном блоке
2) есть утечка памяти - вы не удаляете неиспользуемые блокировки
Я бы сделал это так
Map<Integer, Lock> map = new HashMap<>();
static class Lock {
int count = 1;
}
void func(int i) {
Object lock = getLock(i);
try {
synchronized (lock) {
//
}
} finally {
releaseLock(i);
}
}
private synchronized Object getLock(int i) {
Lock lock = map.get(i);
if (lock != null) {
lock.count++;
} else {
lock = new Lock();
map.put(i, lock);
}
return lock;
}
private synchronized void releaseLock(int i) {
Lock lock = map.get(i);
if (--lock.count == 0) {
map.remove(i);
}
}