This is a successor of my previous question, Is this variable being safely accessed by using synchronization?
For the following program,
Class SubClassB extends SuperClassA {
protected int c;
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized ( (SuperClassA) this) {
c--;
}
}
}
Would the counter "c" be accessed thread safe ? I am not sure that in the "dec()" method, is the SuperClassA cast "this" reference a valid object for the synchronized block ? If yes, would the two synchronized blocks lock the same "this" object ? (As it seems to me that "(SuperClassA) this" is not equal to "this")
This strange simulated code comes from the following real life example where SuperClassA is a base class that is not supposed to be modified,
Class SuperClassA {
protected int c;
public void dec() {
synchronized (this) {
c--;
}
}
}
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
super.dec();
}
}
In this example, the "dec()" method in SubClassB calls its superclass's "dec()" method which performs a lock to a "this" object that I suppose to be "SuperClassA.this". If the locked object in SubClassB's "inc()" method is not exactly the same as the locked object in SubClassB's "dec()" method, then I am wondering the inherited counter "c" in SubClassB may NOT be safely accessed by different threads. I feel that there is some ambiguities in using the "this" reference in synchronized blocks.
In the real life example, if I want SubClassB's counter "c" to be thread safe, do I need to add one more synchronized block in its "dec()" method, like this,
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized (this) {
super.dec();
}
}
}
But it seems that such added block is not elegant and may be redundant !
Does anyone have some ideas on these questions. Thanks in advance.
Lawrence
Synchronized blocks provide granular control over a lock, as you can use arbitrary any lock to provide mutual exclusion to critical section code. On the other hand, the synchronized method always locks either on the current object represented by this keyword or class level lock, if it's a static synchronized method.
A Java synchronized block doesn't allow more than one JVM, to provide access control to a shared resource. The system performance may degrade because of the slower working of synchronized keyword. Java synchronized block is more efficient than Java synchronized method.
synchronized method acquires a lock on the whole object. This means no other thread can use any synchronized method in the whole object while the method is being run by one thread. synchronized blocks acquires a lock in the object between parentheses after the synchronized keyword.
Method Synchronization Synchronized methods enables a simple strategy for preventing the thread interference and memory consistency errors. If a Object is visible to more than one threads, all reads or writes to that Object's fields are done through the synchronized method.
The code is thread-safe, because (SomeObject) this
adn this
are the same object. A cast doesn't transform an object into another object.
The code lacks encapsulation, though, because it lets any subclass access the protected c
field in an unsynchronized way. So, any subclass might use c++
or c--
without any synchronization. The field should be private.
Would the counter "c" be accessed thread safe ?
Yes, it's using the same lock object.
I am not sure that in the "dec()" method, is the SuperClassA cast "this" reference a valid object for the synchronized block ?
Yes.
If yes, would the two synchronized blocks lock the same "this" object ? (As it seems to me that "(SuperClassA) this" is not equal to "this")
Yes. Even if you cast the instance to something it can be casted to (even Object), it'll still refer to the same object.
[...] But it seems that such added block is not elegant and may be redundant !
It is redundant. Extra synchronization is required only if you call multiple synchronized methods and the combined effect must be atomic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With