gpt4 book ai didi

java - 我们可以通过私有(private) getInstance 方法和公共(public) getter setter 方法来创建 Singleton 类吗?

转载 作者:行者123 更新时间:2023-11-30 08:36:58 25 4
gpt4 key购买 nike

Singleton 类不就意味着始终强制存在一个类的单个实例吗?如果是这种情况,与规范不同,我们不能使用私有(private) getInstance 方法在其中使用 getter-setter 方法吗?简而言之,下面的类是 Singleton 类的一个例子吗?为什么/为什么不:-

public class MySingletonClass {
private MySingletonClass mySingletonClass;
private String name;
private MySingletonClass(){

}
private MySingletonClass getSingletonClassReference(){
if(mySingletonClass==null){
mySingletonClass = new MySingletonClass();
}
return mySingletonClass;
}

public static String getName() {
return getSingletonClassReference().name;
}

public static setName(String name) {
getSingletonClassReference().name = name;
}}

编辑由于上面的代码给出了编译时错误,这里是修改后的类代码。问题还是一样,我们不能有公共(public)的 getter-setters 和私有(private)的 getInstance 方法吗?为什么不呢?

public class MySingletonClass {
private static MySingletonClass mySingletonClass;
private String name;
private MySingletonClass(){

}
private static MySingletonClass getSingletonClassReference(){
if(mySingletonClass==null){
mySingletonClass = new MySingletonClass();
}
return mySingletonClass;
}

public static String getName() {
return getSingletonClassReference().name;
}

public static void setName(String name) {
getSingletonClassReference().name = name;
}}

最佳答案

如果问题是:Singleton 可以是可变的吗?答案是肯定的,为什么不呢?但它需要是线程安全的,目前情况并非如此,您的代码中确实存在 2 个问题:

  1. 您不会阻止多个线程创建您的单例,这意味着您可能有多个对象实例违反了单例
  2. 您需要防止同时读取和修改名称,否则您的线程将获得不一致的名称值。

首先这里是如何正确实现一个 Singleton 来进行延迟创建,这显然是您想要的

public class MySingletonClass {
// The constructor must be private to prevent external instantiation
private MySingletonClass(){};
/** The public static method allowing to get the instance */
public static MySingletonClass getInstance() {
return MySingletonClassHolder.INSTANCE;
}
/**
* The static inner class responsible for creating your instance only on demand,
* because the static fields of a class are only initialized when the class
* is explicitly called and a class initialization is synchronized such that only
* one thread can perform it, this rule is also applicable to inner static class
* So here INSTANCE will be created only when MySingletonClassHolder.INSTANCE
* will be called
*/
private static class MySingletonClassHolder {
private static final MySingletonClass INSTANCE = new MySingletonClass();
}
}

这解决了第 1 点,对于第 2 点,您可以在 getNamesetName 这两个方法的声明中添加关键字 synchronized 或简单地将关键字 volatile 添加到变量 name 中。最后一种方法是非阻塞的,速度要快得多,这是这种方法的样子:

public class MySingletonClass {

private volatile String name;
...

关于java - 我们可以通过私有(private) getInstance 方法和公共(public) getter setter 方法来创建 Singleton 类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37513059/

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