Oracle官方併發教程之一個同步類的例子
阿新 • • 發佈:2018-12-23
是表示顏色的類,每一個物件代表一種顏色,使用三個整形數表示顏色的三基色,字串表示顏色名稱。
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時需要小心,避免其處於不一致的狀態。例如一個執行緒執行了以下程式碼:
SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black"); ... int myColorInt = color.getRGB(); //Statement 1 String myColorName = color.getName(); //Statement 2
如果有另外一個執行緒在Statement 1之後、Statement 2之前呼叫了color.set方法,那麼myColorInt的值和myColorName的值就會不匹配。為了避免出現這樣的結果,必須要像下面這樣把這兩條語句繫結到一塊執行:
synchronized (color) { int myColorInt = color.getRGB(); String myColorName = color.getName(); }
這種不一致的問題只可能發生在可變物件上。