此教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
有关Java SE 9及以后版本中更新的语言功能的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息,请参阅JDK发行说明。
类
定义了表示颜色的对象。每个对象都由三个代表主要颜色值的整数和一个给出颜色名称的字符串表示。SynchronizedRGB
public class SynchronizedRGB { // 值必须在0和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(); //语句1 String myColorName = color.getName(); //语句2
如果在语句1之后但在语句2之前另一个线程调用了color.set
,myColorInt
的值将不匹配myColorName
的值。为了避免这种情况,这两个语句必须绑定在一起:
synchronized (color) { int myColorInt = color.getRGB(); String myColorName = color.getName(); }
这种不一致只对可变对象可能发生,对于不可变版本的SynchronizedRGB
不会有此问题。