Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this code Double Checked Locking safe?

I am looking at some code in our app that I think may be encountering a case of "Double-checked locking". I have written some sample code that is similar to what we do.

Can anyone see how this can be experiencing double-checked locking? Or is this safe?

class Foo {
    private Helper helper = null;
    public Helper getHelper() {
        Helper result;
        synchronized(this) {
            result = helper;
        }

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

Base code borrowed from wiki.

like image 446
Aishwar Avatar asked Apr 27 '26 19:04

Aishwar


1 Answers

It's unnecessarily complex, the simplest 'safe' way to do DCL is like so:

class Foo {
  private volatile Helper helper = null;
  private final Object mutex = new Object(); 
  public Helper getHelper() {
    if (helper == null) {
        synchronized(mutex) {
            if (helper == null) {
                helper = new Helper();
            }
        }
    }
    return helper;
  }
}

The key points here being:

  • In the 'happy' case we expect helper to already be assigned, so if it is we can just return it without having to enter a synchronized block.
  • Helper is marked as volatile to let the compiler know that helper can be read from / written to by any thread at any time and it's important that read / writes are not re-ordered.
  • The synchronized block uses a private final variable to synchronize on to avoid a potential performance hit in the case of another area of code synchronizing on the this instance.
like image 177
Rich O'Kelly Avatar answered Apr 29 '26 08:04

Rich O'Kelly



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!