java - 单例上的同步访问

标签 java multithreading synchronization singleton

我有一个关于单例同步的问题。假设我有一个像这样的单例模式:

public class Singleton {

    private final Object obj;

    private static Singleton instance;

    private Singleton(Object obj) {
        this.obj = obj;
    }

    public static synchronized Singleton getInstance(Object obj) {
        if (instance == null) {
            instance = new Singleton(obj);
        }
        return instance;
    }

    public synchronized void methodA() {
        // ...
    }

    public synchronized void methodB() {
        // ...
    }
}

我想同步对其的访问。我有两个假设需要验证。

  1. 假设: 由于所有方法(包括初始值设定项)都是同步的,因此对此 Singleton 的每次访问都是线程安全且同步的。

  2. 假设: 当我想确保一个线程想要调用 methodA() 然后立即调用 methodB() 而没有另一个线程调用单例的方法时,同步是否正确在这样的实例上?

Singleton singleton = Singleton.getInstance(obj);

synchronized (singleton) {
    singleton.methodA();
    singleton.methodB();
}

说明:

1. 假设是否正确,因为非静态方法上的同步会在对象本身上进行同步,并且由于它始终是同一对象,因此访问是同步的?对 getInstance(obj) 的调用会在类本身上同步吗?

2. 假设是否正确,因为使用 getInstance(obj) 每个线程都会获取相同的对象,因此同步是正确的,因为另一个线程将等待同步块(synchronized block) (.. .methodA(); methodB();) 是否退出?

最佳答案

假设我理解正确,你的假设是正确的。我只是想指出,在大多数情况下,您可以使用更简单的单例模式:

public class Singleton {

    private static Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

该字段将以线程安全的方式在第一个静态引用(例如 getInstance())上初始化,无需显式同步。

此外,实例应该是最终

关于java - 单例上的同步访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30692116/

相关文章:

c - 使用两个缓冲区和两个互斥锁的线程同步: C

java - 基于compareTo调用方法?

java - Java如何在指定时间在右下角弹出一个小窗口

java - Android 上的 Flutter VoIP 推送通知

c# - 多线程同步的正确模式? (C#)

java - 使用同步的生产者-消费者

java - 不使用 Array.sort 对多维字符串数组进行排序

java - 如何使用多线程使我的应用程序更快

python - 通过 '%' 实现 python 字符串操作的多线程安全

java - 查找 JVM 中上下文切换或唤醒线程所花费的 CPU 时间