gpt4 book ai didi

Java 单例模式 - 更新实例化变量

转载 作者:行者123 更新时间:2023-11-30 07:54:52 24 4
gpt4 key购买 nike

希望找出有关单例模式的一些信息。

如果我实现如下所示的单例模式,我该怎么做才能使其他类可以更新并查看字段 someString 和 someInt 的更新?

根据我对单例模式的了解,不变性并不是先决条件之一。那么从技术上讲,我可以为字段设置 setter 方法并更改它们,并使这些更改对其他类可见吗?例如,如果我有另外两个类实现 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}

酒吧的输出:

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);
}
}
}

更新:一些愚蠢的拼写错误

最佳答案

您有两个单独的主要方法,因此您可能在单独的 JVM 中运行每个类。相反,创建一个在不同线程中运行每个类的 main 方法,然后运行它。

您还需要将 Foo 中的方法声明为同步或等效的方法,以保证所有线程都能看到更新。

public class Foo {
private static Foo instance;
private String someString;
private int someNum;

private Foo() {
someString = "a";
someNum = 1;
}

public synchronized static Foo getInstance(){
if(instance == null) {
instance = new Foo();
}
return instance;
}

public synchronized void setSomeString(String someString) {
this.someString = someString;
}

public synchronized void setSomeNum(int someNum) {
this.someNum = someNum;
}

@Override
public synchronized String toString() {
return "Foo{" +
"someString='" + someString + '\'' +
", someNum=" + someNum +
'}';
}
}

public class Baz implements Runnable {
public void run() {
Foo foo = Foo.getInstance();
while(true) {
System.out.println("Baz: " + foo);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}


public class Bar implements Runnable {
public void run() {
Foo foo = Foo.getInstance();
foo.setSomeNum(2);
foo.setSomeString("abc");
while(true) {
System.out.println("Foo: " + foo);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}

public class Main {
public static void main(String[] args) throws InterruptedException {
new Thread(new Bar()).start();
new Thread(new Baz()).start();
}
}

关于Java 单例模式 - 更新实例化变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32799017/

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