When using the singleton design pattern, do other methods need to use synchronized keyword to ensure thread safety?

感情迁移 提交于 2019-12-10 18:27:35

问题


I want to ensure that the following class is thread-safe, should I use the synchronized keyword for other methods? Or use a thread-safe data structure to store Email. What should I do?

public class RecycleStation {
    private static volatile RecycleStation uniqueInstance;
    private static List<Email> recycleEmailList ;

    private RecycleStation() {
        recycleEmailList = new ArrayList<>();
    }

    public static RecycleStation getInstance() {
        if (uniqueInstance == null) {
            synchronized (RecycleStation.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new RecycleStation();
                }
            }
        }
        return uniqueInstance;
    }

    public void RecycleEmail(Email email) {
        recycleEmailList.add(email);
    }

    public void deleteEmail(Email email) {
        recycleEmailList.remove(email);
    }

    public void clear() {
        recycleEmailList.clear();
    }

}

回答1:


First, a Singleton pattern is best implemented as Enum in Java Second, each email manipulation function (clear, Recycle, delete) should be synchronized to ensure thread safety (the link is about an Enum, but the same holds about each and every Sinlgeton implementation):

public synchronized void RecycleEmail(Email email)



回答2:


It is better to use a thread-safe, atomic data structure for your Emails than setting synchronized in each of the update methods. Synchronization uses the lock mechanism of the OS, which is an expensive operation and should be avoided.

I'd use ConcurrentLinkedQueue (example below).

Regarding the class itself - The Lazy-Initialization design pattern for a thread-safe singleton might be a good solution too.

It has mostly pro's in your case:

  • You avoid the use of synchronized in getInstance()
  • Slightly improves start-up time
  • Thread-safe :)

Edit: Have a look at this article to better understand why this implementation is thread-safe. @Rafael has made a good point: lazy Initialization, by its own, doesn't necessarily mean thread-safety.

After all is said and done, here's an implementation:

public class RecycleStation  {
    private static RecycleStation uniqueInstance; //You don't need `volatile` here
    private static ConcurrentLinkedQueue<Email> recycleEmailList;

    // Here it all begins:
    private static class SingletonHolder {
        private static RecycleStation  instance = new RecycleStation();
    }
    public static RecycleStation getInstance() {
        return SingletonHolder.instance;
    }
    private RecycleStation () {
        recycleEmailList = new ConcurrentLinkedQueue<>();
    }

    // class functions:
    public void RecycleEmail(Email email) {
        recycleEmailList.add(email);
    }

    public void deleteEmail(Email email) {
        recycleEmailList.remove(email);
    }

    public void clear() {
        recycleEmailList = new ConcurrentLinkedQueue<>();
    }
}


来源:https://stackoverflow.com/questions/55506718/when-using-the-singleton-design-pattern-do-other-methods-need-to-use-synchroniz

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!