4
\$\begingroup\$

I am using a singleton in my DAO. Would I be better off with static methods? Also, should I be worried about synchronization of the singleton and my data structures?

public class RAMUserDAO implements GenericDAO<User, String, Boolean>
    {
        private static RAMUserDAO   userDAO = null;
        private Map<String, User>   userList;
        private Map<String, User>   banList;
        private static Logger       log     = LOG.PRODUCTION;

        private RAMUserDAO()
            {
                userList = new ConcurrentHashMap<String, User>();
                banList = new ConcurrentHashMap<String, User>();
            }

        public static RAMUserDAO getRAMUserDAO()
            {
                if (userDAO == null)
                    {
                        synchronized (RAMUserDAO.class)
                            {
                                if (userDAO == null)
                                    {
                                        userDAO = new RAMUserDAO();
                                    }
                            }
                    }
                return userDAO;
            }
    }
\$\endgroup\$
1

2 Answers 2

2
\$\begingroup\$

Double-checked locking is broken and must be avoided. The article explains the reasons in depth and provides several alternatives. In this case you can follow the advice in the "Making it work for static singletons" section by immediately initializing the static field.

public class RAMUserDAO implements GenericDAO<User, String, Boolean>
{
    private static RAMUserDAO userDAO = new RAMUserDAO();
    ...

    public static RAMUserDAO getRAMUserDAO() {
        return userDAO;
    }
}

The Java memory model guarantees that the userDAO reference will not be written until all writes have been flushed. The field will be initialized when the class is loaded and safely available to all threads. This has the added benefit of avoiding synchronization to access the DAO.

\$\endgroup\$
8
  • \$\begingroup\$ I read the website and I think I'm implementing the solution for JDK 5 and above at the bottom. How am I not implementing what they have? Is the helper object different then getRAMUserDAO()? \$\endgroup\$ Aug 12, 2014 at 1:01
  • \$\begingroup\$ So what you saying is that I would get synchronization without overhead with static? \$\endgroup\$ Aug 12, 2014 at 1:08
  • \$\begingroup\$ @user3590149 You have to make the field volatile for that to work in JDK 5+, but it won't work in earlier JDKs (probably not an issue). For such a simple class I see no reason to pay the synchronization penalty when you can simply initialize the field directly. \$\endgroup\$ Aug 12, 2014 at 1:08
  • \$\begingroup\$ I think I been leaning you way. I think I adjust if I find problems down the road. \$\endgroup\$ Aug 12, 2014 at 1:09
  • \$\begingroup\$ @user3590149 The JVM's class loader synchronizes the loading of each class so you'd pay it only once when the class is first loaded. Your method doesn't need to be synchronized at all. \$\endgroup\$ Aug 12, 2014 at 1:09
2
\$\begingroup\$

Your spacing is all over the place, and the double null check against userDAO seems redundant.

I'm not making a comment on the big picture on whether or not the singleton is necessary, but I'd certainly fix getRAMUserDAO() up to look more like this:

public static RAMUserDAO getRAMUserDAO() {
    synchronized (RAMUserDAO.class) {
        if (userDAO == null) {
            userDAO = new RAMUserDAO();
        }
        return userDAO;
    }
}

The Egyptian-style braces are just my general preference. I don't know if there's a Java standard for how to do the braces.

\$\endgroup\$
6
  • \$\begingroup\$ I'm trying to implement Double Checked Locking for multithreading. I'm not sure if I will need it though. \$\endgroup\$ Aug 12, 2014 at 0:42
  • \$\begingroup\$ Yes, that's the correct Java brace style, a variation of K&R where the opening brace for classes also goes on the same line. I've never heard of any style called Egyptian, though. :) \$\endgroup\$ Aug 12, 2014 at 0:46
  • \$\begingroup\$ Same-line opening braces (as in my answer) is known as Egyptian style. blog.codinghorror.com/content/images/uploads/2012/07/… \$\endgroup\$
    – nhgrif
    Aug 12, 2014 at 0:48
  • 1
    \$\begingroup\$ You shouldn't change the code in your answer. I was commenting on the most-likely preferred formatting style of someone who would maintain this code. \$\endgroup\$
    – nhgrif
    Aug 12, 2014 at 0:52
  • 1
    \$\begingroup\$ @user3590149 When writing code for your own projects, pick a style that you like and use it consistently. The only issue with it is that it quickly leads to line-wrapping (and horizontal scroll bars here), but that's less important than consistency. \$\endgroup\$ Aug 12, 2014 at 0:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.