0

I was told unsafe double-checked-locking is bad, for it may returns null on some race conditions, so it should be avoided.

Unsafe Double-Checked Locking idiom:

public class UnsafeDCLFactory {
    private Singleton instance;

    public Singleton get() {
        if (instance == null) {  // read 1, check 1
            synchronized (this) {
                if (instance == null) { // read 2, check 2
                    instance = new Singleton();
                }
            }
        }
        return instance; // read 3
    }

    static class Singleton {
        private Date d;
        public Singleton() {
            this.d = new Date();
        }
    }
}

when we call get() method, null may be returned though it's very very rare. But i just wonder why null can be returned? Does it mean even if 'read 1' read a non-null value, 'read3' can still read a null one?

gaols
  • 341
  • 5
  • 13
  • inside the for loop, thread t1 and thread t2 share the same factory instance in order to create a race condition which may produce a null value when calling facotry.get(). – gaols Jan 07 '19 at 13:14
  • Your implementation is incorrect. – Raedwald Jan 07 '19 at 13:34
  • this is not a duplicate question @Raedwald. i have edit the question. i definitely know my implemention is incorrect, so i named the class UnsafeDCLFactory . – gaols Jan 07 '19 at 14:06
  • @gaols You need to **justify** why this is not a duplicate *in the body of your question*. Edit your question, and it will be reconsidered for reopening. – Raedwald Jan 07 '19 at 15:36
  • @Raedwald updated the question. – gaols Jan 08 '19 at 01:19

1 Answers1

0

Yes, it is possible (although very, very unlikely).

Have a look at this article about safe publication in Java. It also handles the double-checked locking and the possible "null" return.

Coronero
  • 160
  • 1
  • 9
  • could you please create an test or some code snippet which can catch the null . – gaols Jan 07 '19 at 13:19
  • The article links to the [code snippets](http://hg.openjdk.java.net/code-tools/jcstress/file/31dbc6275b2d/tests-custom/src/main/java/org/openjdk/jcstress/tests/singletons/) used. The article also states, that on x86 it will most likely not happen. But it is possible on other architectures like ARM – Coronero Jan 07 '19 at 13:29
  • The way you're doing it, you'll never get a null, but you might find that you've created the singleton more than once. Since you haven't declared the member variable to be volatile, the compiler will optimize away read 2. Even if another thread has initialized it, the second thread will do so again. Also, without a little randomness, your code will fall into the same pattern every time, so as long as it succeeds once, it will do so every time. – Zag Jan 07 '19 at 13:29