private boolean connected = false;
...
synchronized (connected) {
if (!connected)
return;
// If connected, change to disconnected and proceed, otherwise do nothing
connected = false;
}
Which gives rise to 3 vital things to know about synchronization:
1) Synchronize on the object, not the reference
This maybe a surprise to some, but it is actually the object at the end of a reference you synchronize on, and NOT the access to an instance variable. If you would like that, you should synchronize on this instead. If you don't trust me on this, try assigning a variable to null and synchronize it. It will throw a NPE because it cannot access the object to lock.2) Don't synchronize on global objects, such as Boolean etc.
In this case, the private boolean will be autoboxed into either Boolean.TRUE or Boolean.FALSE. Synchronizing either one of these instances will lock for all similar synchronized access even in other classes (If others does the same mistake). Keep synchronization as small as possible and don't use objects that others can actually see.3) Don't reassign the variable containing the synchronization.
By reassigning the value of the reference, the buck actually stops here. No more synchronization. This is because when others come to the synchronized block, they will find another object than the one that was locked. You see this occasionally with collections:synchronized (map) {
map=new HashMap();
lock using one object, then create a new instance. Using collections as synchronization point is often seen, but may be worse than you anticipate (See point 2 above, and this article as well)
0 comments:
Post a Comment