【发布时间】:2016-06-12 22:33:47
【问题描述】:
我有一个单例工厂(编辑:重命名为“加载器”以避免与工厂模式混淆)创建对象(在我的示例 DAO 中)或在已创建的情况下返回它们:
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;
}
}
首先,你们觉得这段代码有什么问题吗?
在此示例中,是否需要为每种方法使用不同的锁,还是应该只使用 1 个全局锁?唯一的全局锁会发生死锁吗?如果不是,唯一的缺点是,如果某个线程使用锁来创建 DAO,而另一个线程想创建另一个 DAO,它必须等待锁被释放?
谢谢。
【问题讨论】:
-
唯一的缺点?远不止于此。像全局可见的对象不会缩放。谷歌有一个单身猎人来识别和删除他们:reddit.com/comments/ikf9z
-
我认为那里甚至没有工厂设计。检查这个tutorialspoint.com/design_pattern/factory_pattern.htm
-
@duffymo “全局可见的对象不会缩放”你是什么意思?
-
@NathanHughes 这是一个我不能使用 Spring 或任何 DI 框架的项目,我只想创建 1 次 DAO 并重用它们。
-
让我为您简化:不要创建单例或所有这些锁定代码。汇集您的连接并在尽可能窄的范围内使用它们。学习 Spring——他们编写的 JDBC 框架比你想象的要好。
标签: java multithreading locking singleton synchronized