java - 使用单例设计模式时,其他方法是否需要使用synchronized关键字来保证线程安全?

标签 java design-patterns singleton

我想保证后面的类是线程安全的,是否应该对其他方法使用synchronized关键字?或者使用线程安全的数据结构来存储Email。我该怎么办?

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

}

最佳答案

最好为您的电子邮件使用线程安全原子 数据结构,而不是在每个更新方法中设置同步。同步使用操作系统的lock机制,这是一个昂贵的操作,应该避免。

我会使用 ConcurrentLinkedQueue(下面的示例)。

关于类(class)本身 - Lazy-Initialization线程安全单例的设计模式也可能是一个很好的解决方案。

在您的情况下,它主要是专业人士:

  • 避免在 getInstance() 中使用 synchronized
  • 略微缩短了启动时间
  • 线程安全:)

编辑:看看this article更好地理解为什么这个实现是线程安全的。 @Rafael 提出了一个很好的观点:惰性初始化本身并不一定意味着线程安全。

说了这么多,下面是一个实现:

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

关于java - 使用单例设计模式时,其他方法是否需要使用synchronized关键字来保证线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55506718/

相关文章:

java - 降低圈复杂度的最佳方法

design-patterns - 设计问题: Owning a class with many different subclasses

java - 单例模式: Multiton?

java - 有没有一种简单的方法可以将日志记录从依赖项插入到类中?

java - 如何执行从 JFileChooser 到包含文件夹的 JList 的拖放操作

Java 事件队列。为什么一切都应该在 invokelater 方法中?

java - 部分可变的 API 类,具有供客户端使用的通用变量持有者

multithreading - 在 Scala 上创建线程本地对象

python - 如何以编程方式将基于 "custom class"的单例对象转换为 python 模块?

java - 如何在 Eclipse 项目中包含 mysql 数据库