0

I am reading concurrency in practice and have some misunderstanding.
quote:

the real problem with DCL is the assumption that the worst thing that can happen when reading the shared object reference without synchronization is to erroneously see a stale value (in this case, null); in that cse the DCL idiom compensates for this risk by trying again with the lock held. But the worst case is actually considerably wrong - it is possible to see a current value of the reference but stale values for the object's states, meaning that the object could be seen to be in an invalid or incorrect state.

after Brian Goetz writes that DCL will work in current memory model using volatile:

public class DoubleCheckLociing{

   private static volatile Resource resource;

   public static Resource getInstance(){
       if(resource == null){
           synchronized(DoubleCheckLociing.class){
               if(resource == null){
                   resource = new Resource();
               }
            }
       } 
       return resource;
   }
}

I am not sure if understand the phrase about state correct.

Lets imagine that Resource class looks like this:

class Resource{
    private Date date = new Date();//mutable thread unsafe class
    private int k = 10;

    public Date getDate(){
        return date;
    }

   public int getK(){
        return k;
    }

}

Does I have guaranties that getInstance always return correct resource which always return correct k (10) and date?

gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • *Does I have guaranties that getInstance always return correct resource which always return correct k (10) and date?*. So you just want a confirmation whether *Brian Goetz* is right? – Chetan Kinger Feb 05 '17 at 15:39
  • I need confirmation that my understanding correct. My previous understanding was strictly another. I thought that problem with 2 reads of shared reference. First can return !=nul but second can be null – gstackoverflow Feb 05 '17 at 15:54
  • And you did not find a single answer on the site that confirmed this? – Chetan Kinger Feb 05 '17 at 16:02
  • I am not strong in termins thus I cannot build search string properly – gstackoverflow Feb 05 '17 at 16:04
  • What does the `dcl` (Digital Command Language) tag have to do with this question? – HABO Feb 06 '17 at 14:23

2 Answers2

3

With the volatile in place you do have those guarantees. Without the volatile you do not.

When one thread writes the volatile variable resource, the operation includes a 'memory barrier' that ensures that everything it wrote before that, like the initialization of the instance fields, is written out to system memory first.

When another thread reads resource, it includes a memory barrier that ensures that no reads performed after that will see values that were cached from system memory before that read.

These two memory barriers ensure that if a thread sees an initialized resource variable, then it will also see properly initialized fields in that object.

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
0

Does I have guaranties that getInstance always return correct resource which always return correct k (10) and date?

Yes and no. As @Matt points out, if the field is volatile then you are guaranteed that all of the fields of Resource will be published appropriately when it is accessed by another thread which is the important part of the double-check-locking example you quote. The volatile memory-barriers ensure this.

However, your Resource contains non-final fields that may be mutable (if a setter method was added or not listed). If you make your fields final then actually you can dispense with the volatile because final fields are guaranteed to be published when the reference to your Resource is published.

private final Date date = new Date();
private final int k = 10;

As you mention however, this doesn't fully save you because Date is also mutable. You need to make sure that your code (or other code) does not call any setter methods on the date field, then you will be ok.

This is a good example about how important it is to track mutability in threaded programs.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • But if I don't execute matations of my objects I have guaranties to see values I set in constructor(inline in my case) – gstackoverflow Feb 05 '17 at 19:59
  • If they are final yes. If they are not final then the `volatile` gives you those guarantees, yes @gstackoverflow. – Gray Feb 05 '17 at 20:04