river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gregg Wonderly <gr...@wonderly.org>
Subject Re: Possible multi-threading bug
Date Fri, 03 Dec 2010 14:19:37 GMT
On 12/2/2010 3:48 PM, Patricia Shanahan wrote:
> Gregg Wonderly wrote:
> ...
>> A second issue is that if you are designing a "container" class that others
>> might use in multiplicity such that it could end up in a container, and
>> perhaps as a key data structure, it can be better to create an internal
>> locking object to perform synchronization on so that if the user of your class
>> starts using your class as a locking object, the internal locking does not
>> impact unrelated code paths.
> ...
>
> For container objects, I would give the opposite advice, and recommend making
> the container itself the lock object.

There are cases for both I believe.  ConcurrentHashMap, for example has no locks 
performed on the instance.   All locking is internal using mechanisms other than 
synchronized.

The primary issue with using an internal lock, for me, is that I've found that I 
end up with less opportunity for circular wait if I am in complete control of 
when a lock is asserted.

For things where atomic views need to maintained through multiple operations on 
the same instance, then a single global view lock will be important.  As the 
user of the container instance, you are more able to understand that need in 
your application, so locking is your responsibility.

Many people have complained about CHM not being "the lock" itself, but it really 
comes down to the fact that since it does not use synchronized actions 
internally, it can not make the object be "the lock".

With this in mind, I've started trying to internalize more locking so that for 
things that I do need to "adjust internal performance" on, I don't have to go 
everywhere else and change locking use to be in line with the change from 
synchronized to Lock.

Locking with instances via synchronized was convenient, but I'd suggest that not 
doing that provides a more plastic model that you can more readily adjust.

I also find that I will put more application operations into the APIs to help me 
control and optimize those usage patterns.  This seems to help me create more 
relevant/useful APIs and fewer "containers".  I.e. more simple algorithms end up 
in the class implementation instead of strewn about the application.

Gregg Wonderly

Mime
View raw message