I have a portion of code that needs to be thread safe. It is code that loads and modifies an object from the database based on its ID. I want to avoid synchronizing on just the Integer ID variable, so I am attempting to implement the solution offered in this thread: https://stackoverflow.com/a/659939/3561422
However, I am not creating a cache so I have nothing in place to manage the objects added to the map. I want to avoid a memory leak situation. I have looked into using a WeakHashMap, but that is apparently not thread-safe. I have created a map as follows, but the GC does not appear to be cleaning up the references I create.
private static Map<Integer, Object> locks = Collections.synchronizedMap(new WeakHashMap<Integer, Object>())
Is there something I am missing here that would make this solution work? Is WeakHashMap actually safe for me to use here?
Some example code:
public static void mainMethod(Integer id){
Object lockObject = getMapObject(id);
synchronized (lockObject) {
Object dbObj = loadDBObjFromDB(id);
//Do pre execution checks
if (dbObj.isInUse()) {
//fail here
}
dbObj.setAsInUseAndCommitToDB();
}
actOnObj(dbObj);
}
private static Object getMapObject(final Integer id) {
locks.putIfAbsent(id, new Object);
return locks.get(id);
}
Basically, I need to mark something in the database as in use. If another thread comes in and wants to do something on it, it needs to see if it is already in use. If it is, I fail and give the user feedback. I need to lock around loading, checking if it is in use, and updating that it is in use. I would like to use the map to avoid locking on an Integer object