单件工厂中的同步和锁定

时间:2016-02-29 18:45:08

标签: java multithreading locking singleton synchronized

我有一个单件工厂(编辑:重命名"加载器"以避免与工厂模式混淆)创建对象(在我的示例中为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,那么它是否必须等待锁被释放?

感谢。

1 个答案:

答案 0 :(得分:1)

您的示例似乎有点混乱,因为您阻止DaoLoader的构造函数可见,但您并未阻止Dao构造函数可见。拥有一个加载器类也可以变成事物的倾倒场,它鼓励按层而不是按功能进行组织。

您可以考虑使用Initialization-on-Demand holder idiom

this is max size: 3
this is the mult result: 12
size of answer in bytes: 8
size of the answer array: 2

在调用访问它的方法之前,不会初始化holder static class,因为它是在第一次访问时初始化的(并且类初始化是串行的),不需要同步。