Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
类定义了表示颜色的对象。每一个对象表示一种颜色,使用三个整数表示颜色的三基色,用一个字符串表示颜色名称。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
使用时必须小心,避免其处于不一致的状态。例如,假设一个线程执行以下代码:
SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black"); ... int myColorInt = color.getRGB(); //Statement 1 String myColorName = color.getName(); //Statement 2
如果另一个线程在语句 1 之后但在语句 2 之前调用 color.set
,则 myColorInt
的值将与 myColorName
的值不匹配。为了避免这种结果,必须将两个语句绑定在一起:
synchronized (color) { int myColorInt = color.getRGB(); String myColorName = color.getName(); }
这种不一致只会发生于可变对象 它不会是 SynchronizedRGB
的不可变版本的问题。