background image
<< Race Condition | Buffer overflow/underflow >>

Inconsistent synchronization

<< Race Condition | Buffer overflow/underflow >>
2.4
Some common bug patterns dealing with synchronization
2.4.1
Inconsistent synchronization
(frequent, major) [13] [19]
This bug indicates that the class contains a mix of locked and unlocked accesses. So if there are
some locked accesses on shared variables and some other accesses are unlocked, then this may be
an alarm for improper synchronization. Here we may give more importance to writes than reads
of a shared variable. This is more often when we synchronize one of the methods in a class that is
intended to be thread safe and forget some other.
2.4.2
Incorrect lazy initialization of static field
(rare, major) [13] [19]
A volatile static field has a set of `release semantics' and `acquire semantics' for reading and
writing the data item. So if there is a lazy initialization of a non-volatile field shared by different
threads, then it can possibly cause a synchronization problem. This is because, the compiler may
reorder the execution steps and the threads are not guaranteed to see the expected initialization of
the shared object which was non-volatile.
Hence such data items have to be declared as static volatile to rectify this problem. If we declare
as static volatile, then the order of execution can be preserved by the semantics of the volatile field
[23].
2.4.3
Naked notify in method
(rare, minor) [13] [10]
This bug is not necessarily an indication of error, but it can act as a possible alarm. A call to
notify() or notifyAll() was made without any accompanying modification to mutable object state.
A notify method is called on a monitor when some condition occurs, and there is another thread
which is waiting for it has to be called. For the condition to be meaningful, it must involve a shared
object between the threads which has been modified [13].
2.4.4
Method spins on field
(rare, catastrophic) [10]
This method spins in a loop which reads a field. The compiler may legally take out the read
out of the loop, turning the code into an infinite loop. The class should be changed so that it uses
proper synchronization (including wait and notify calls). [10] [13]
l o c k =0;
w h i l e ( t r u e )
{
if ( l o c k = = 0 )
/* if c o m p i l e r m o v e s t h i s outside ,
* it c a u s e s an i n f i n i t e l o o p */
b r e a k ;
}
So when such waiting is needed, it is better to use proper synchronization constructs like wait
and notify, instead of using primitive spin locks.
2.5
Data and Arithmetic errors
2.5.1
Uninitialised memory
(rare, major) [26]
6