Singleton类不仅仅意味着强制执行类的单个实例吗?如果是这种情况,与标准不同,我们不能在私有getInstance方法中使用getter-setter方法吗? 总之,下面是Classton类的一个例子吗?为什么/为什么不: -
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;
}}
修改 由于上面的代码给出了编译时错误,这里是修改后的类代码。问题还是一样,我们不能有一个公共的getter-setter和私有的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;
}}
答案 0 :(得分:1)
根据已编辑的代码,您仍然无法保证MySingletonClass类的单实例创建。仍有可能两个实例将由两个并发调用创建。但是在这个例子中,我认为它不会影响你的方法中的其他过程!有道理。
鉴于你的代码:
考虑A和B想要调用setter方法, 先致电话。
getSingletonClassReference()将在setter内部调用,B同时调用setter。请求到达 if(mySingletonClass == null){ 它创造了一个对象。在那之前B到达条件null检查器并且将是真的,基本上它导致创建对象的两个实例。 如果我们假设B等待mySingletonClass = new MySingletonClass();和请求到达getSingletonClassReference()。name = name;然后B恢复执行,然后B覆盖名称,将忽略更改。
在您的示例中没有意义,但在实际应用程序中,它可能会在运行时导致错误并丢失数据。
最好在代码中应用同步,如下所示:
public static Singleton getInstanceDC()
{
if (_instance == null) {
// Single Checked
synchronized (Singleton.class)
{
if (_instance == null)
{ // Double checked
_instance = new Singleton();
}
}
}
return _instance;
}
答案 1 :(得分:1)
如果问题是:Singleton
是否可变?答案是肯定为什么不呢?但它必须是thread safe
,而现在情况并非如此,您的代码中确实存在2个问题:
singleton
,这意味着您的对象的多个实例可能会违反singleton
的合同首先,这里是如何正确实现一个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点,您可以在synchronized
和getName
这两种方法的声明中添加关键字setName
,或者只需添加关键字volatile
变量name
。最后一种方法是非阻塞这么快,这就是这种方法的样子:
public class MySingletonClass {
private volatile String name;
...
答案 2 :(得分:0)
单例意味着每个JVM只能有一个实例。这意味着在您的情况下,变量mySingletonClass
必须是静态的(私有静态MySingletonClass mySingletonClass;`)以及get / setname。
关于规范,你的班级用户可能更难看到这是一个单身人士。
答案 3 :(得分:0)
您必须使方法getSingletonClassReference
公开,但构造函数是私有的,因此您无法创建访问该方法的对象。因此,在这种情况下,您可以将方法设置为静态,以便其他类可以在不创建对象的情况下访问该方法。但是在你的getSingletonClassReferenc
方法中,条件不对。在这里,您可以创建一个静态计数器来检查只创建了一个实例。
答案 4 :(得分:0)
是。那可以创造。 但是,您上面编写的代码需要修改。 getter,setter,getSingletonClassReference()和mySingletonClass字段应该是静态的。 但是,重要的是这不方便。