本文介绍了同步并锁定单例工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个单例工厂(重命名为"loader",以避免与工厂模式混淆),该工厂创建对象(在我的示例DAO中)或将其返回(如果已创建):

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;
    }
}

首先,你们看到这段代码有什么问题吗?
在此示例中,是否需要为每个方法使用不同的锁,还是应该仅使用1个全局锁?唯一的全局锁会发生死锁吗?如果不是,唯一的缺点是,如果某个线程使用该锁来创建DAO,而另一个线程想要创建另一个DAO,则它必须等待锁被释放?

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?

谢谢.

推荐答案

您的示例似乎有些困惑,因为您是在阻止DaoLoader的构造函数可见,但不是在阻止DaoLoader的构造函数可见.拥有装载程序类也可以成为事物的垃圾场,并且它鼓励按层而不是按功能进行组织.

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.

您可以考虑使用 Initialization-on-Demand持有人惯用语:

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;
    }
}

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

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.

这篇关于同步并锁定单例工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:24
查看更多