Consider the following method:
public void upsert(int customerId, int somethingElse) {
// some code which is prone to race conditions
}
I want to protect this method from race conditions, but this can only occur if two threads with the same customerId
are calling it at the same time. If I make the whole method synchronized
it will reduce the efficiency and it's not really needed. What I really want is to synchronize it around the customerId
. Is this possible somehow with Java? Are there any built-in tools for that or I'd need a Map
of Integers
to use as locks?
Also feel free to advice if you think I'm doing something wrong here :)
Thanks!
The concept you're looking for is called segmented locking or striped locking. It is too wasteful to have a separate lock for each customer (locks are quite heavyweight). Instead you want to partition your customer ID space into a reasonable number of partitions, matching the desired degree of parallelism. Typically 8-16 would be enough, but this depends on the amount of work the method does.
This outlines a simple approach:
private final Object[] locks = new Object[8];
synchronized (locks[customerId % locks.length]) {
...implementation...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With