Whenever a question pops up on SO about Java synchronization, some people are very eager to point out that synchronized(this)
should be avoided. Instead, they c
The reason not to synchronize on this is that sometimes you need more than one lock (the second lock often gets removed after some additional thinking, but you still need it in the intermediate state). If you lock on this, you always have to remember which one of the two locks is this; if you lock on a private Object, the variable name tells you that.
From the reader's viewpoint, if you see locking on this, you always have to answer the two questions:
An example:
class BadObject {
private Something mStuff;
synchronized setStuff(Something stuff) {
mStuff = stuff;
}
synchronized getStuff(Something stuff) {
return mStuff;
}
private MyListener myListener = new MyListener() {
public void onMyEvent(...) {
setStuff(...);
}
}
synchronized void longOperation(MyListener l) {
...
l.onMyEvent(...);
...
}
}
If two threads begin longOperation()
on two different instances of BadObject
, they acquire
their locks; when it's time to invoke l.onMyEvent(...)
, we have a deadlock because neither of the threads may acquire the other object's lock.
In this example we may eliminate the deadlock by using two locks, one for short operations and one for long ones.