Double checked locking Article

后端 未结 10 609
别那么骄傲
别那么骄傲 2020-12-09 20:06

I was reading this article about \"Double-Checked locking\" and out of the main topic of the article I was wondering why at some point of the article the author uses the nex

相关标签:
10条回答
  • 2020-12-09 20:42

    Since Java 5, you can make double-checked locking work by declaring the field volatile.

    See http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html for a full explanation.

    0 讨论(0)
  • 2020-12-09 20:43

    Regarding this idiom there is a very advisable and clarifying article:

    http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html?page=1

    On the other hand, I think what dhighwayman.myopenid means is why the writer has put one synchronized block referring to the same class (synchronized(Singleton.class)) within another synchronized block referring to the same class. It may happen as a new instance (Singleton inst = instance;) is created within that block and to guarantee it to be thread-safe it's necessary to write another synchronized.

    Otherwise, I can't see any sense.

    0 讨论(0)
  • 2020-12-09 20:44

    See the Google Tech Talk on the Java Memory Model for a really nice introduction to the finer points of the JMM. Since it is missing here, I would also like to point out Jeremy Mansons blog 'Java Concurrency' esp. the post on Double Checked locking (anyone who is anything in the Java world seems to have an article on this :).

    0 讨论(0)
  • 2020-12-09 20:45

    The point of locking twice was to attempt to prevent out-of-order writes. The memory model specifies where reorderings can occur, partly in terms of locks. The lock ensures that no writes (including any within the singleton constructor) appear to happen after the "instance = inst;" line.

    However, to go deeper into the subject I'd recommend Bill Pugh's article. And then never attempt it :)

    0 讨论(0)
  • 2020-12-09 20:45

    Jon Skeet is right: read Bill Pugh's article. The idiom that Hans uses is the precise form that won't work, and should not be used.

    This is unsafe:

    private static Singleton instance;
    
    public static Singleton getInstance() {
      if (instance == null) {
        synchronized(Singleton.class) {
          if (instance == null) {
            instance = new Singleton();
          }
        }
      }
      return instance;
    }
    

    This is also unsafe:

    public static Singleton getInstance()  
    {
        if (instance == null)
        {
            synchronized(Singleton.class) {      //1
                Singleton inst = instance;         //2
                if (inst == null)
                {
                    synchronized(Singleton.class) {  //3
                        inst = new Singleton();        //4
                    }
                    instance = inst;                 //5
                }
            }
        }
        return instance;
    }
    

    Don't do either of them, ever.

    Instead, synchronise the whole method:

        public static synchronized Singleton getInstance() {
          if (instance == null) {
            instance = new Singleton();
          }
          return instance;
        }
    

    Unless you're retrieving this object a zillion times a second the performance hit, in real terms, is negligible.

    0 讨论(0)
  • 2020-12-09 20:55

    For Java 5 and better there is actually a doublechecked variant that can be better than synchronizing the whole accessor. This is also mentioned in the Double-Checked Locking Declaration :

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

    The key difference here is the use of volatile in the variable declaration - otherwise it does not work, and it does not work in Java 1.4 or less, anyway.

    0 讨论(0)
提交回复
热议问题