问题
I have a singleton factory (edit: renamed "loader" to avoid confusion with factory pattern) that creates objects (in my example DAOs) or returns them if already created:
public class DAOLoader {
private static final DAOLoader INSTANCE = new DAOLoader();
private UserDAO userDAO;
private MessageDAO messageDAO;
private final Object lockUserDAO = new Object();
private final Object lockMessageDAO = new Object();
private DAOLoader() {}
public static DAOLoader getInstance() {
return INSTANCE;
}
public UserDAO getUserDAO() {
if (userDAO == null) {
synchronized(lockUserDAO) {
if (userDAO == null) userDAO = new UserDAO();
}
}
return userDAO;
}
public MessageDAO getMessageDAO() {
if (messageDAO == null) {
synchronized(lockMessageDAO) {
if (messageDAO == null) messageDAO = new MessageDAO();
}
}
return messageDAO;
}
}
First, do you guys see anything wrong with this code?
In this example, is a different lock for each method required or should I just use 1 global lock? Would a deadlock happen with a unique global lock? If not, the only drawback would be that if the lock is used by some thread to create a DAO and another thread would like to create another DAO, it would have to wait for the lock to be released?
Thanks.
回答1:
Your example seems a bit confused because you're preventing the DaoLoader's constructor from being visible but you're not preventing the Dao constructors from being visible. Also having a loader class can turn into a dumping ground for things, and it encourages organizing by layer rather than by feature.
You might consider using the Initialization-on-Demand holder idiom:
public class UserDao {
private UserDao() {}
String findById(Long id) {
return "foo";
}
private static class LazyUserDaoHolder {
static final UserDao USER_DAO_INSTANCE = new UserDao();
}
public static UserDao getInstance() {
return LazyUserDaoHolder.USER_DAO_INSTANCE;
}
}
The holder static class isn't initialized until the method accessing it is called, since it is initialized on first access (and class initialization is serial) no synchronization is required.
来源:https://stackoverflow.com/questions/35707141/synchronized-and-locks-in-singleton-factory