The Java™ Tutorials — Concurrency :A Synchronized Class Example 一個同步類的例子
原文地址:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncrgb.html
關鍵點
- 理解本文案例中,可變對象帶來的讀取不一致問題。
全文翻譯
The class, SynchronizedRGB, defines objects that represent colors. Each object represents the color as three integers that stand for primary color values and a string that gives the name of the color.
SynchronizedRGB類定義了表示顏色的對象。每個對象代表了通過三個整數來表示的顏色(這三個整數代表三原色),以及顏色的名字。
public class SynchronizedRGB {
// Values must be between 0 and 255.
private int red;
private int green;
private int blue;
private String name;
private void check(int red,
int green,
int blue) {
if (red < 0 || red > 255
|| green < 0 || green > 255
|| blue < 0 || blue > 255) {
throw new IllegalArgumentException();
}
}
public SynchronizedRGB(int red,
int green,
int blue,
String name) {
check(red, green, blue);
this.red = red;
this.green = green;
this.blue = blue;
this.name = name;
}
public void set(int red,
int green,
int blue,
String name) {
check(red, green, blue);
synchronized (this) {
this.red = red;
this.green = green;
this.blue = blue;
this.name = name;
}
}
public synchronized int getRGB() {
return ((red << 16) | (green << 8) | blue);
}
public synchronized String getName() {
return name;
}
public synchronized void invert() {
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
name = "Inverse of " + name;
}
}
SynchronizedRGB must be used carefully to avoid being seen in an inconsistent state. Suppose, for example, a thread executes the following code:
SynchronizedRGB 必須小心使用以避免讀取結果不一致。舉個例子,假如,一個線程執行了下面的代碼:
SynchronizedRGB color =
new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB(); //Statement 1
String myColorName = color.getName(); //Statement 2
If another thread invokes color.set after Statement 1 but before Statement 2, the value of myColorInt won’t match the value of myColorName. To avoid this outcome, the two statements must be bound together:
如果另一個線程在語句1後,語句2前調用了color.set,那麼myColorInt和myColorName的值就無法匹配了。爲了避免這樣的結果,兩個語句的執行必須被綁定:
synchronized (color) {
int myColorInt = color.getRGB();
String myColorName = color.getName();
}
This kind of inconsistency is only possible for mutable objects — it will not be an issue for the immutable version of SynchronizedRGB.
此樣的不一致性僅對可變對象而言,這在不可變版本的SynchronizedRGB中並不是問題。