Question about Double-checked locking

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Question about Double-checked locking

Tutika Chakravarthy
Hi All,
I have some code like this :

result = map.get(key);


if (result == null ) {

Object mutex = mutexFactory.getMutex(key);

synchronized (mutex) {
result = map.get(key);

if (result == null) {
        result = dataSource.load(key);

        if (result != null)
        map.put(key, result);
        else
        mutexFactory.removeMutex(key);

        }
 }
}

Here mutexFactory returns different monitors based on
the key .
I am using HashMap to store and retrieve the values .
If the value is not there in the map , I should load
the value from DataBase using dataSource.

I would like to know whether the above code falls
under "Double-checked locking" problem.


If so , Can I avoid it using new util.concurrent.Lock
interface classes ?

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Question about Double-checked locking

David Holmes-3
Yes it is the failed double-checked-locking idiom. But it is also broken in
the locking strategy anyway - see below.

No changing from synchronized to Lock doesn't make a difference to the
double-check part. You must establish a "happens-before" relationship
between the thread setting the value in the map, and the thread reading it.

The locking strategy is broken because you use a different Object for
different keys. So multiple threads can be concurrently trying to put()
different key/result pairs. The hashtable must be protected from concurrent
access using the *same* Lock/object in all threads.

Cheers,
David Holmes


> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of Tutika
> Chakravarthy
> Sent: Sunday, 14 May 2006 7:17 PM
> To: [hidden email]
> Subject: [concurrency-interest] Question about Double-checked locking
>
>
> Hi All,
> I have some code like this :
>
> result = map.get(key);
>
>
> if (result == null ) {
>
> Object mutex = mutexFactory.getMutex(key);
>
> synchronized (mutex) {
> result = map.get(key);
>
> if (result == null) {
> result = dataSource.load(key);
>
> if (result != null)
> map.put(key, result);
> else
> mutexFactory.removeMutex(key);
>
> }
>  }
> }
>
> Here mutexFactory returns different monitors based on
> the key .
> I am using HashMap to store and retrieve the values .
> If the value is not there in the map , I should load
> the value from DataBase using dataSource.
>
> I would like to know whether the above code falls
> under "Double-checked locking" problem.
>
>
> If so , Can I avoid it using new util.concurrent.Lock
> interface classes ?
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Question about Double-checked locking

David Holmes-3
I forgot to mention that the HashMap isn't protected by a lock at all during
the get() operations, and get()'s can't happen concurrently with put()'s
(though multiple get()'s can be concurrent).

David Holmes

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of David
> Holmes
> Sent: Sunday, 14 May 2006 7:30 PM
> To: Tutika Chakravarthy; [hidden email]
> Subject: RE: [concurrency-interest] Question about Double-checked
> locking
>
>
> Yes it is the failed double-checked-locking idiom. But it is also
> broken in
> the locking strategy anyway - see below.
>
> No changing from synchronized to Lock doesn't make a difference to the
> double-check part. You must establish a "happens-before" relationship
> between the thread setting the value in the map, and the thread
> reading it.
>
> The locking strategy is broken because you use a different Object for
> different keys. So multiple threads can be concurrently trying to put()
> different key/result pairs. The hashtable must be protected from
> concurrent
> access using the *same* Lock/object in all threads.
>
> Cheers,
> David Holmes
>
>
> > -----Original Message-----
> > From: [hidden email]
> > [mailto:[hidden email]]On Behalf Of Tutika
> > Chakravarthy
> > Sent: Sunday, 14 May 2006 7:17 PM
> > To: [hidden email]
> > Subject: [concurrency-interest] Question about Double-checked locking
> >
> >
> > Hi All,
> > I have some code like this :
> >
> > result = map.get(key);
> >
> >
> > if (result == null ) {
> >
> > Object mutex = mutexFactory.getMutex(key);
> >
> > synchronized (mutex) {
> > result = map.get(key);
> >
> > if (result == null) {
> > result = dataSource.load(key);
> >
> > if (result != null)
> > map.put(key, result);
> > else
> > mutexFactory.removeMutex(key);
> >
> > }
> >  }
> > }
> >
> > Here mutexFactory returns different monitors based on
> > the key .
> > I am using HashMap to store and retrieve the values .
> > If the value is not there in the map , I should load
> > the value from DataBase using dataSource.
> >
> > I would like to know whether the above code falls
> > under "Double-checked locking" problem.
> >
> >
> > If so , Can I avoid it using new util.concurrent.Lock
> > interface classes ?
> >
> > __________________________________________________
> > Do You Yahoo!?
> > Tired of spam?  Yahoo! Mail has the best spam protection around
> > http://mail.yahoo.com
> > _______________________________________________
> > Concurrency-interest mailing list
> > [hidden email]
> > http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Question about Double-checked locking

Tutika Chakravarthy
> > No changing from synchronized to Lock doesn't make
> a difference to the
> > double-check part. You must establish a
> "happens-before" relationship
> > between the thread setting the value in the map,
> and the thread
> > reading it.

Can you elaborate "happens-before" relationship part?
Suppose If I replace HashMap wih ConcurrentHashMap,
How can I avoid double-checked locking problem.
My Aim is that if the value is not present in the map
for a key , load it from Database. Otherwise simply
use get() method  and return it.

Tutika

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Question about Double-checked locking

Doron Rajwan
In reply to this post by Tutika Chakravarthy

It seems to me that you want two different type of
locks here:
1. locking the map, for "fast" actions.
2. locking a specific key, in order not to load it
from database twice.

If this is correct, just change the map to
sychronizedMap or to ConcurrentHashMap, and the code
will be correct. It will still have locks, even in the
read-only case, however.

Doron


______________________________________________________
Doron Rajwan, [hidden email], http://www.rajwan.org

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Question about Double-checked locking

David Holmes-3
In reply to this post by Tutika Chakravarthy
> Can you elaborate "happens-before" relationship part?

The happens-before relationship is the formal part of the Java Memory Model
that controls the possible outcomes for concurrent reads and writes of a
variable. If a thread A writes a value V to a variable X and thread B reads
X, then for B to see V the write by A must "happen-before" the read by B.
Otherwise B can see a value previously written to X.

Within a thread each program statement happens-before the next, according to
program order. To create cross-thread happens-before relationships you have
to use synchronization tools, like Locks, sync regions, or volatiles. In
simple terms if thread B acquires a given lock after thread A releases it,
then everything that happened in thread A before the releases happens-before
anything in thread B that occurs after the acquire - so any values written
by A will be read by B.

I'm sure someone else can give you a quick link to further details.

> Suppose If I replace HashMap wih ConcurrentHashMap,
> How can I avoid double-checked locking problem.
> My Aim is that if the value is not present in the map
> for a key , load it from Database. Otherwise simply
> use get() method  and return it.

There's a good answer coming on this - stay tuned.

Right now I have to fly.

Cheers,
David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest