[英]Singleton, threads and synchronization
我正在关注《 Head First设计模式》(第5章,单例模式)。
他们谈论的线程的重叠进入方法getInstance()
时, synchronized
不使用关键字。
我如何在屏幕上看到线程的两种行为的差异?
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
原因是两个线程同时在单例中修改了相同的实例变量“值”。
现在,将单词“ synchronized”添加到方法“ setValue”和“ printValue”中,然后再次运行。 您将看到,所有行仅由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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.