Understanding volatile in DCL

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

Understanding volatile in DCL

罗傅聪
It is mentioned in the wiki of double-checked locking idiom(https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java) that DCL without introducing “volatile” keyword is broken:

// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
    private Helper helper;

    public Helper getHelper() {
        if (helper == null) {    
            synchronized(this) {    
                if (helper == null) {    
                    helper = new Helper();
                }
            }
        }    
        return helper;
    }

    // other functions and members…
}

It’s broken because a thread may obtain a partially constructed object (the variable “helper” may be initialized before constructor “new Helper()” finished due to reordering).

I am wondering is there another possible of why that is broken that, the “helper” may be initialized more than once?

Say Thread1 and Thread2 are now concurrently trying to get the helper instance, and T1 obtains the monitor(enter the synchronized block) while T2 waits.

Then T1 initialized the helper and returned, T2 entered the synchronized block. However, without the “volatile” keyword, T2 may not see the update of the helper variable that were made by T1. So T2 may think that "helper == null” is true, and thus initialize the helper again.

Is the above possible? Thanks in advance!

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

Re: Understanding volatile in DCL

Sam Munkes
writes cannot be reordered after the synchronized block (MonitorExit), so by the time T2 acquires the monitor it will see the fully published helper.
the problem would be with other threads that do not acquire the lock.


On Tue, Aug 4, 2015 at 8:55 PM, luo.fucong <[hidden email]> wrote:
It is mentioned in the wiki of double-checked locking idiom(https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java) that DCL without introducing “volatile” keyword is broken:

// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
    private Helper helper;

    public Helper getHelper() {
        if (helper == null) {    
            synchronized(this) {    
                if (helper == null) {    
                    helper = new Helper();
                }
            }
        }    
        return helper;
    }

    // other functions and members…
}

It’s broken because a thread may obtain a partially constructed object (the variable “helper” may be initialized before constructor “new Helper()” finished due to reordering).

I am wondering is there another possible of why that is broken that, the “helper” may be initialized more than once?

Say Thread1 and Thread2 are now concurrently trying to get the helper instance, and T1 obtains the monitor(enter the synchronized block) while T2 waits.

Then T1 initialized the helper and returned, T2 entered the synchronized block. However, without the “volatile” keyword, T2 may not see the update of the helper variable that were made by T1. So T2 may think that "helper == null” is true, and thus initialize the helper again.

Is the above possible? Thanks in advance!

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



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

Re: Understanding volatile in DCL

Joe Bowbeer
In reply to this post by 罗傅聪
Double init is not possible *because* of the synchronized block, which provides a critical section and visibility.

If double init were possible in this code snippet, it would also be possible without the initial null check.

The volatile is only needed because of the introduction of the initial null check.

On Tue, Aug 4, 2015 at 8:55 PM, luo.fucong <[hidden email]> wrote:
It is mentioned in the wiki of double-checked locking idiom(https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java) that DCL without introducing “volatile” keyword is broken:

// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
    private Helper helper;

    public Helper getHelper() {
        if (helper == null) {    
            synchronized(this) {    
                if (helper == null) {    
                    helper = new Helper();
                }
            }
        }    
        return helper;
    }

    // other functions and members…
}

It’s broken because a thread may obtain a partially constructed object (the variable “helper” may be initialized before constructor “new Helper()” finished due to reordering).

I am wondering is there another possible of why that is broken that, the “helper” may be initialized more than once?

Say Thread1 and Thread2 are now concurrently trying to get the helper instance, and T1 obtains the monitor(enter the synchronized block) while T2 waits.

Then T1 initialized the helper and returned, T2 entered the synchronized block. However, without the “volatile” keyword, T2 may not see the update of the helper variable that were made by T1. So T2 may think that "helper == null” is true, and thus initialize the helper again.

Is the above possible? Thanks in advance!

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



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