【发布时间】:2015-09-26 15:55:49
【问题描述】:
想弄清楚单例模式。
如果我实现如下所示的单例模式,我该怎么做才能让其他类更新并查看字段 someString 和 someInt 的更新?
从我读到的关于单例模式的内容来看,不变性不是先决条件之一。那么从技术上讲,我可以为字段设置方法并更改它们并使这些更改对其他类可见吗?例如,如果我有另外两个类实现 Runnable 并每隔几秒打印 Foo 的字段。我试过了,结果是每个类只看到自己的更新,而其他类都看不到。
public class Foo {
private static Foo instance;
private String someString;
private int someNum;
private Foo(){
someString = "a";
someNum = 1;
}
public static Foo getInstance(){
if(instance == null){
instance = new Foo();
}
return instance;
}
public void setSomeString(String someString) {
this.someString = someString;
}
public void setSomeNum(int someNum) {
this.someNum = someNum;
}
@Override
public String toString() {
return "Foo{" +
"someString='" + someString + '\'' +
", someNum=" + someNum +
'}';
}
}
---更新--- 添加了 2 个类(下面的 Baz 和 Bar)并使用 setter 更新了 Foo 并覆盖了 toString()。
首先运行 Baz,我希望它每秒打印 foo.toString() 的最新值。
然后运行 Bar,它首先更新 Foo 的字段,然后每秒打印 foo.toString()。来自 Bar 的更新仅对 Bar 可见,而对 Baz 不可见。
来自 Baz 的输出:
1443284013576 Foo{someString='a', someNum=1}
1443284014576 Foo{someString='a', someNum=1}
1443284015576 Foo{someString='a', someNum=1}
1443284016577 Foo{someString='a', someNum=1}
1443284017577 Foo{someString='a', someNum=1}
1443284018577 Foo{someString='a', someNum=1}
Bar 的输出:
1443284016416 Foo{someString='abc', someNum=2}
1443284017417 Foo{someString='abc', someNum=2}
1443284018417 Foo{someString='abc', someNum=2}
1443284019418 Foo{someString='abc', someNum=2}
1443284020418 Foo{someString='abc', someNum=2}
public class Baz {
public static void main(String[] args) throws InterruptedException {
Foo foo = Foo.getInstance();
while(true){
System.out.println(foo);
Thread.sleep(1000);
}
}
}
public class Bar{
public static void main(String[] args) throws InterruptedException {
Foo foo = Foo.getInstance();
foo.setSomeNum(2);
foo.setSomeString("abc");
while(true){
System.out.println(foo);
Thread.sleep(1000);
}
}
}
更新:一些愚蠢的错别字
【问题讨论】:
-
仅供参考,为了线程安全,您应该考虑将
getInstance()设为同步方法。 -
你能用你试过的设置器发布这个例子吗?
-
当你像
public static synchronized Foo getInstance()这样声明getInstance方法时会发生什么? -
@BYTERIDER 见上文
-
@JamesKPolk 如果我的问题与同步有关,我不希望看到更新或获得 ConcurrentModificationException 吗?
标签: java design-patterns singleton