gpt4 book ai didi

java - 单例、线程和同步

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

我正在阅读《Head First Design Patterns》一书(第 5 章,单例模式)。

他们谈到在未使用 synchronized 关键字时线程与方法 getInstance() 的重叠。

如何在屏幕上看到线程的两种行为的差异?

  public class ChocolateBoiler {    

private boolean empty;
private boolean boiled;
private static ChocolateBoiler chocolateBoilerInstance;

public ChocolateBoiler() {
empty = true;
boiled = false;
}

public static (synchronized) ChocolateBoiler getInstance() {
if (chocolateBoilerInstance == null) {
chocolateBoilerInstance = new ChocolateBoiler();
}
return chocolateBoilerInstance;
}

public void fill() {
if (isEmpty()) {
empty = false;
boiled = false;
// fill the boiler with a milk/chocolate mixture
}
}

public void drain() {
if (!isEmpty() && isBoiled()) {
// drain the boiled milk and chocolate
empty = true;
}
}

public void boil() {
if (!isEmpty() && !isBoiled()) {
// bring the contents to a boil
boiled = true;
}
}

public boolean isEmpty() {
return empty;
}

public boolean isBoiled() {
return boiled;
}

public static void main(String[] args) {

ChocolateBoiler boiler = ChocolateBoiler.getInstance();
boiler.fill();
boiler.boil();
boiler.drain();
}
}

最佳答案

你的例子太复杂了。我创建了另一个,更简单,请看下面的代码。如果按原样运行它,您将在控制台中看到混合了 0 和 1 的行,如下所示:

11111111111111111111000000000000111111111111111111
11111111111111111111110000000000001111111111111111

原因是两个线程同时修改了单例中的同一个实例变量“value”。

现在向“setValue”和“printValue”这两个方法添加单词“synchronized”并再次运行它。您会看到,所有行仅由 0 或 1 组成。它们不再混合。

00000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111

原因是,任何时候只有一个线程修改变量,因为“同步”阻止了不同线程同时访问单例对象。

代码如下:

public class Main {

public static class Singleton {

private static Singleton instance = new Singleton();

public static Singleton getInstance() {
return instance;
}

private char[] value = new char[50];

private Singleton() {
}

public void printValue() {
for (int i = 0; i < value.length; i++) {
System.out.print(value[i]);
}
System.out.println();
}

public void setValue(String newValue) {
for (int i = 0; i < newValue.length() && i < value.length; i++) {
value[i] = newValue.charAt(i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// Ignore
}
}
}

}

public static void main(String[] args) {
final int MAX = 100000;

Thread thread1 = new Thread() {
@Override
public void run() {
for (int i = 0; i < MAX; i++) {
Singleton.getInstance().setValue("00000000000000000000000000000000000000000000000000");
yield();
}
}
};

Thread thread2 = new Thread() {
@Override
public void run() {
for (int i = 0; i < MAX; i++) {
Singleton.getInstance().setValue("11111111111111111111111111111111111111111111111111");
yield();
}
}
};

Thread thread3 = new Thread() {
@Override
public void run() {
for (int i = 0; i < MAX; i++) {
System.out.printf("%5d: ", i);
Singleton.getInstance().printValue();
yield();
}
}
};

thread1.start();
thread2.start();
thread3.start();
}

}

关于java - 单例、线程和同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50659333/

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