[英]Can a synchronized method of an instance be locked by synchronized statement
I have run into a code piece in official tutorial of concurrency : 我在并发的官方教程中遇到了一段代码:
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;
}
}
My question is : 我的问题是:
If a thread uses set
method, can another thread use one of the synchronized methods, or the other way around ? 如果一个线程使用
set
方法,另一个线程可以使用其中一个同步方法,还是相反?
No, they can't. 不,他们不能。 At least not while you are inside the
synchronized(this)
block. 至少当您位于
synchronized(this)
块中时,才不会。 Declaring a non-static method as synchronized
has the same effect as putting everything inside the method into a synchronized(this) {}
block. 将非静态方法声明为已
synchronized
具有与将方法中的所有内容都放入synchronized(this) {}
块相同的效果。
Thus, while one thread is inside a non-static method declared as synchronized
, no other thread may execute either a synchronized
method or a synchronized(this) {}
block. 因此,当一个线程位于声明为
synchronized
的非静态方法内部时,其他任何线程都不能执行synchronized
方法或synchronized(this) {}
块。
For methods declared as static
in the class ThisClass
: They are handled the same way as if the contents of the method was inside a synchronized(ThisClass.class) {}
block. 对于在类
ThisClass
声明为static
方法:对其处理方式与该方法的内容在synchronized(ThisClass.class) {}
块内一样。
For your example, if you wonder why this does not work correctly: 对于您的示例,如果您想知道为什么这不能正常工作:
SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB(); //Statement 1
String myColorName = color.getName(); //Statement 2
getRGB()
and getName()
do lock on this
. getRGB()
和getName()
确实this
进行了锁定。 But between the two method calls the lock is released again so that another thread could acquire it, then release it, and only then the first thread could finally execute getName()
. 但是在这两个方法调用之间,再次释放了锁,以便另一个线程可以获取该锁,然后释放它,只有第一个线程才可以最终执行
getName()
。 Thus another thread could change the color between the the RGB
and the Name
getter so the name and RGB returned would not fit to the same color. 因此,另一个线程可以更改
RGB
和Name
getter之间的颜色,因此返回的name和RGB将不适合同一颜色。
If you do it like this: 如果您这样做:
SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
synchronized(color) {
int myColorInt = color.getRGB(); //Statement 1
String myColorName = color.getName(); //Statement 2
}
In this case the lock on the object is not released between getRGB()
and getName()
so that no thread could acquire it at this time. 在这种情况下,对象的锁定不会在
getRGB()
和getName()
之间释放,因此此时没有线程可以获取它。
No; 没有;
synchronized
methods will synchronize on this
. synchronized
方法将this
同步。
Also, this is poor code; 而且,这是糟糕的代码; the entire class should be immutable, solving all threading problems without synchronization.
整个类应该是不可变的,无需同步即可解决所有线程问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.