I have a class with some property (partition in the example below)
class Car {
public String partition;
....
}
and I have a function
private void doSomething(Car car){
//
Object obj = getLock(car); // should write this function
synchronized (obj){
// do work here
}
}
If I have 2 instances of the Car object
from 2 different threads the function doSomething is called. the synchronize block should sync only objects with the same "partition" value. When 2 car object have a different partition key they can both enter the block of code at the same time
I was wondering how to write the "getLock" function. Should I use some map
Map<String,Object> ?
Is there a better way prevent 2 object with same property to enter the critical section?
If you definitely want to use locking, I would have a look at a striped lock. Some pseudo-code:
class CarManager{
final Object[] lockStripe = new Object[Runtime.availableProcessors()*4];
public CarManager(){
for(int k=0;k<lockStripe.length;k++){
lockStripe[k]=new Object();
}
}
Object getLock(Car car){
int hash = car.partition.hashCode();
int lockIndex;
if (hash == Integer.MIN_VALUE) {
lockIndex = 0;
} else {
lockIndex = abs(hash) % lockStripe.length;
}
return lockStripe[lockIndex];
}
public void doSomething(Car car){
synchronized(getLock(car)){
...
}
}
This approach will ensure that: