我在并发的官方教程中遇到了一段代码:
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;
}
}
我的问题是:
如果一个线程使用set
方法,则另一个线程可以使用其中一个同步方法,还是相反?
不,他们不能。至少在您位于synchronized(this)
街区内时不是如此。将非静态方法声明为synchronized
与将方法内部的所有内容放入一个synchronized(this) {}
块具有相同的效果。
因此,当一个线程位于声明为的非静态方法内部时synchronized
,其他任何线程都不能执行synchronized
方法或synchronized(this) {}
块。
对于static
在类中声明的方法ThisClass
:处理方法的方式与方法的内容在synchronized(ThisClass.class) {}
块内一样。
对于您的示例,如果您想知道为什么这不能正常工作:
SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB(); //Statement 1
String myColorName = color.getName(); //Statement 2
getRGB()
并getName()
锁定this
。但是在这两个方法调用之间再次释放了锁,以便另一个线程可以获取该锁,然后释放它,只有第一个线程才可以最终执行getName()
。因此,另一个线程可能会更改theRGB
和Name
getter之间的颜色,因此返回的名称和RGB将不适合同一颜色。
如果您这样做:
SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
synchronized(color) {
int myColorInt = color.getRGB(); //Statement 1
String myColorName = color.getName(); //Statement 2
}
在这种情况下,对象之间的锁定不会在之间释放getRGB()
,getName()
因此此时没有线程可以获取它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句