Можно ли синхронизировать метод по параметру?
Например - я получаю person для какого-то метода и хочу выполнить какую-то операцию для person, но если несколько потоков вызывают этот метод для одного и того же человека, я хочу сделать это один за другим.
private void dosomething(Long id, Person person) {
dosomethingelse(id, person);
}
Как вызывать dosomethingelse (id, person) только для одного и того же идентификатора один за другим?но я хочу, чтобы этот код для разных идентификаторов можно было назвать многопоточным
Я написал этот код, но, возможно, что-то здесь не так или что-то может быть лучше.
public static class LatchByValue <T> {
public void latch(T value, ConsumerWithException<T> consummer) throws Exception {
CountDownLatch latch = new CountDownLatch(1);
try {
CountDownLatch previousLatch = null;
// we are checking if another thread is already calling this method with the same id
// if sync has CountDownLatch so another thread is already calling this method
// or we put our latch and go on
while ((previousLatch = sync.putIfAbsent(value, latch)) != null) {
try {
// we are waiting for another thread, we are waiting for all threads that put their latch before our thread
previousLatch.await();
} catch (InterruptedException e) {
return;
}
}
consummer.accept(value);
} finally {
latch.countDown();
sync.remove(value, latch);
}
}
private ConcurrentHashMap<T, CountDownLatch> sync = new ConcurrentHashMap<>();
}
Пример:
LatchByValue<Long> latch = new LatchByValue<>();
private void dosomething(Long id, Person person) {
latch.latch(
id,
currentId -> { dosomethingelse(currentId, person); }
);
}