实例的同步方法可以被同步语句锁定吗
Can a synchronized method of an instance be locked by synchronized statement
我已经运行写进官方并发教程的一段代码了:
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
.
同步
此外,这是糟糕的代码;整个class应该是不可变的,解决所有没有同步的线程问题。
不,他们不能。至少当你在 synchronized(this)
块内时不会。
将非静态方法声明为 synchronized
与将方法内的所有内容都放入 synchronized(this) {}
块中具有相同的效果。
因此,当一个线程在声明为 synchronized
的非静态方法中时,没有其他线程可以执行 synchronized
方法或 synchronized(this) {}
块。
对于在 class ThisClass
中声明为 static
的方法:它们的处理方式与方法内容在 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()
。因此,另一个线程可以更改 RGB
和 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()
之间没有释放,因此此时没有线程可以获取它。
我已经运行写进官方并发教程的一段代码了:
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
.
此外,这是糟糕的代码;整个class应该是不可变的,解决所有没有同步的线程问题。
不,他们不能。至少当你在 synchronized(this)
块内时不会。
将非静态方法声明为 synchronized
与将方法内的所有内容都放入 synchronized(this) {}
块中具有相同的效果。
因此,当一个线程在声明为 synchronized
的非静态方法中时,没有其他线程可以执行 synchronized
方法或 synchronized(this) {}
块。
对于在 class ThisClass
中声明为 static
的方法:它们的处理方式与方法内容在 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()
。因此,另一个线程可以更改 RGB
和 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()
之间没有释放,因此此时没有线程可以获取它。