In my app I have a "Manager" class that has a reference to a DAO class which loads data from DB and populate a HashMap as a cache solution.
Here is a snippet
class UserManager {
private final UserDAO userDAO;
private final Map<Long, User> users;
private final StampedLock lock = new StampedLock();
public UserManager() {
loadUsersFromDB();
}
// 99% of the times this method is called
public getUserById(long id) {
long stamp = lock.readLock();
try {
return users.get(id);
} finally {
lock.unlock(stamp);
}
}
// This is done once when CTOR calls it and from time to time
// by explicitly calling it from outside.
public void loadUsersFromDB() {
Map<Long, User> loadedUsers = userDAO.loadUsers();
long stamp = lock.writeLock();
try {
this.users = loadedUsers;
} finally {
lock.unlock(stamp);
}
}
}
This code work in a multithreaded environment, and the concern here is the use of StampedLock
in this situation is an OVERKILL since most of the time it does READ operations and once in a while a simple load from DB and assignment to a class member.
I'm thinking to remove the StampedLock
and instead use a simple AtomicReference<Map<Long, User>>
, this way most of the time it's going to be a simple get
and once in a while a set
.
What do you think??