On Nov 13, 2007, at 18:02, Chris Bowditch wrote:
Hi Chris
<snip/>
Just looked closer, and I may have found a slightly better way of
dealing with it.
Since the cause of the problem is CacheCleaners interfering with
rehash(), maybe the below patch is a better approach.
Once rehash() has been entered, and has acquired the lock on the
first segment, set a flag. A CacheCleaner will then only be
launched if there is no rehash in progress.
Your patch has been running all day in my tests and I haven't seen
the NPE, so it looks good. Before I commit it I have one question:
how does this mechanism avoid CacheCleaner threads clearing the ref
attribute if they are already running when the rehash method is
called. Having the flag in rehash is a bit like a one way sync
lock. I would have thought it would be safer for cache cleaner
threads and the rehash method to synchronize on a common object so
that neither interferes with each other.
WDYT?
A splendid idea!
I already thought my approach to be lacking somewhere, although it
was too late last night to see where exactly. First off, the flag
should, of course be declared 'volatile'. If not, then there is no
guarantee a thread will see the most recent state. More importantly,
there is the matter of cleanups that were already running at the time
rehash() started acquiring its locks, as you point out.
Introducing another dummy Object to synchronize on, seems like a very
clean solution. The flag could still be used to avoid unnecessary
cleanups or rehashes from being started. Synchronizing on a mutual
object would still launch them, but they would merely have to wait.
Regarding your observation of the OutOfMemoryError: this might need
investigating. Do you have any indication as to which types of
objects are leaking?
Cheers
Andreas