Very interesting reference about the double checked locking idiom. I was 
unaware of the problems, and had actually read some of the papers advocating 
it. 

I do a lot of multithreaded Java work in critical environments, and probably 
need a refresher on these issues. Can you recommend any good books or online 
resources that may debunk other conventional thread-safety wisdom in light of 
modern processing architecture and the latest Java memory model revisions? 

----- Original Message ----- 
From: "Tim Peierls" <[EMAIL PROTECTED]> 
To: [email protected] 
Sent: Saturday, October 6, 2007 2:53:41 PM (GMT-0500) America/New_York 
Subject: Re: Thread-safety in Guard 

On 10/6/07, Jerome Louvel < [EMAIL PROTECTED] > wrote: 


I have made the following changes to Guard in SVN 1.0 branch: 
- secrets is now a ConcurrentHashMap instance 
- getSecrets() lazily instantiates the secrets field in a synchronized block: 

Unfortunately, unless *all* access to the secrets field is done inside 
"synchronized (this) {...}" -- including all read access -- this code is still 
not correct. I notice that you expose a setSecrets method in 1.1 -- since 
you're exposing the map itself with getSecrets, there is no need for this 
method; it's not clear what its behavior should be in the presence of 
concurrent access to the secrets field. 

I think it would be better to make secrets final and not expose setSecrets -- 
or if you are already committed to exposing it, implement it as something like 

public void setSecrets(Map<String, char[]> secrets) { 
this.secrets.clear(); 
this.secrets.putAll(secrets); 
} 

Interleaved calls to setSecrets might not behave the way you expect -- but you 
probably shouldn't be making concurrent calls to setSecrets anyway. 




public Map<String, char[]> getSecrets() { 
if ( this.secrets == null) { 
synchronized (this) { 
if (this.secrets == null) { 
this.secrets = new ConcurrentHashMap<String, char[]>(); 
} 
} 
} 

return this.secrets; 
} 

This is known as the double-checked locking idiom , and it is broken. Don't use 
it. 




In addition, the getSecrets() method in SVN trunk (future 1.1) returns a 
ConcurrentMap instance instead of just Map. 

Cool. 



Also the "scheme" and "realm" properties have setters in 1.1, so no reason to 
mark them final. 

But in that case they need to be properly synchronized. In this case, you could 
make the fields volatile. The other way is to make sure that they are accessed 
only while holding a synch lock (the same lock each time). Leaving them 
non-final is not correct. 

--Tim Peierls 

Reply via email to