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 ?
No, they can't. At least not while you are inside the synchronized(this)
block. Declaring a non-static method as synchronized
has the same effect as putting everything inside the method into a synchronized(this) {}
block.
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.
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.
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
. 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()
. 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.
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.
No; synchronized
methods will synchronize on this
.
Also, this is poor code; the entire class should be immutable, solving all threading problems without synchronization.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.