Consider the following method:
public void upsert(int customerId, int somethingElse) {
// some code which is prone to race conditions
}
private static final Set lockedIds = new HashSet<>();
private void lock(Integer id) throws InterruptedException {
synchronized (lockedIds) {
while (!lockedIds.add(id)) {
lockedIds.wait();
}
}
}
private void unlock(Integer id) {
synchronized (lockedIds) {
lockedIds.remove(id);
lockedIds.notifyAll();
}
}
public void upsert(int customerId) throws InterruptedException {
try {
lock(customerId);
//Put your code here.
//For different ids it is executed in parallel.
//For equal ids it is executed synchronously.
} finally {
unlock(customerId);
}
}