If you have a nested instance class, synchronizing on this in the inner class is not the same as synchronizing on this in the outer class. This may seem obvious, but it is worth noting because the inner class can refer to methods of either the inner or the outer class in a seemingly ambiguous manner (without explicit qualification). Here's an example program, and its output:
public class WhatIsSyncQualThis {
class IJustDriftedAway {
void superFoo() {
synchronized(IJustDriftedAway.this) {
if( Thread.holdsLock(WhatIsSyncQualThis.this) )
System.out.println("1 - held");
}
synchronized(this) {
if( Thread.holdsLock(WhatIsSyncQualThis.this) )
System.out.println("2 - held");
}
synchronized(WhatIsSyncQualThis.this) {
if( Thread.holdsLock(this) )
System.out.println("3 - held");
}
synchronized(this) {
if( Thread.holdsLock(this) )
System.out.println("4 - held");
}
}
}
void fooIt() {
(new IJustDriftedAway()).superFoo();
}
public static void main(String[] args) {
System.out.println("Running");
(new WhatIsSyncQualThis()).fooIt();
System.out.println("Done");
}
}
Output:
Output:
Running
4 - held
Done
If you know how nested instance classes are implemented, this is not at all surprising. A separate class is created that takes as a constructor argument a reference to an instance of the outer class. So there are two separate instances upon which we are synchronizing.