gpt4 book ai didi

java - SingleTon 类未同步并返回多个实例

转载 作者:行者123 更新时间:2023-12-04 20:03:33 25 4
gpt4 key购买 nike

我下面的代码有问题。从同一进程的多个线程调用同一个单例类时,我得到了同一个单例类的多个实例。我期望该程序只打印一次“创建实例”,但它打印了 3 次(即每个线程)。

package SingleTon;

class SingleTon implements Runnable {
String name;
int salary;
private static SingleTon singleTonInstance;

SingleTon() {

}

public static SingleTon getInstance() {
if (singleTonInstance == null) {
synchronized (SingleTon.class) {
System.out.println("Creating instance");
singleTonInstance = new SingleTon();
}
}
return singleTonInstance;
}

@Override
public void run() {
System.out.format("Thread %s is starting\n",Thread.currentThread().getName());
getInstance();
}

}

package SingleTon;

public class SingleTonDemo {

public static void main(String[] args) {
System.out.println("test");
SingleTon t = new SingleTon();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
t1.start();
t2.start();
t3.start();
}

}

输出:

test
Thread Thread-0 is starting
Thread Thread-2 is starting
Thread Thread-1 is starting
Creating instance
Creating instance
Creating instance

最佳答案

您需要更改以下内容:

1) 将默认构造函数设为私有(private)。正如所写,它是包私有(private)的,可以被同一包中的其他类调用。

private SingleTon() {
}

完成此操作后,您的 SingleTonDemo 类将无法再调用构造函数,并将被迫使用 getInstance() 方法。目前,每次调用构造函数都会创建一个新实例。

2) 同步整个getInstance() 方法。正如所写,2 个单独的线程可以获得 singleTonInstance 的 null 值,因此每个线程都会创建一个新实例。

    public static SingleTon getInstance() {

2a) 确保类只有一个实例的另一种方法是使用静态初始化。在静态变量的声明中,您创建对象:

private static SingleTon singleTonInstance = new SingleTon();

JVM 将确保只调用一次。这也改进了您的 getInstance 方法,因为您可以将其更改为:

public static SingleTon getInstance() {
return singleTonInstance;
}

这种方法的优点是不仅 getInstance 方法更简单,而且不会产生同步开销。

关于java - SingleTon 类未同步并返回多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54431660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com