initialization safety questions

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

initialization safety questions

JSR166 Concurrency mailing list
I'm studying the topic of initialization safety and want to make sure my understanding is correct.

The following object doesn't provide initialization safety since none of the fields are final

    class Foo_1{
        private int f1;
        private int f2;

        public Foo_1(){
            f1=1;
            f2=2;
        }
    }

Foo_2 will provide initialization safety because all the fields are final.
   
    class Foo_2{
        private final int f1;
        private final int f2;

        public Foo_2(){
            f2=2;
            f1=1;
        }
    }

Also Foo_3 is broken. f1 has no issues, but f2 is not final therefor another thread could observe a Foo_3 instance with f2 not being initialized.

    class Foo_3{
        private final int f1;
        private int f2;

        public Foo_3(){
            f1=1;
            f2=2;
        }
    }

The broken nature of the Foo_3 example is mentioned here:

The question is about the following:

class Foo_4{
        private int f1;
        private final int f2;

        public Foo_4(){
            f1=1;
            f2=2;
        }
    }

If I understand the JMM correctly then this example is broken as well. Initially I got confused by a excellent post from Shiplev: https://shipilev.net/blog/2014/safe-public-construction/#_safe_initialization where he states that if any field is final (and the reference doesn't escape), safe initialization works. But he is referring to how it actually is implemented; not about the specification.

So is it correct to say that Foo_4 is doesn't support safe initialization?

If f2 would be made volatile, then the object is supporting safe initialization because in this case the f1=1 can't jump after the f2=2.
  


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

Re: initialization safety questions

JSR166 Concurrency mailing list
>If f2 would be made volatile, then the object is supporting safe
initialization because in this case the f1=1 can't jump after the f2=2

No, that would not save the day. You would lose "safety initialization" for both fields in that case because non of them would be final. And volatile store in a constructor does not prevent reading the default value in case of unsafe publication. This has already been discussed:


Regards,
Valentin

On Wed, Sep 26, 2018, 14:18 Valentin Kovalenko <[hidden email]> wrote:
Hi Peter,

Yes, according to the specification, there is no guarantee of what you are calling safe initialization in example 4.

You may want to take a look at this presentation: https://sites.google.com/site/aboutmale/techblog/javafinal (there is also a link to a talk by my former colleague Vladimir Sitnikov, but that talk is in Russian language).

Regards,
Valentin


On Wed, Sep 26, 2018, 10:56 <[hidden email]> wrote:
Send Concurrency-interest mailing list submissions to
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        http://cs.oswego.edu/mailman/listinfo/concurrency-interest
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Concurrency-interest digest..."


Today's Topics:

   1. initialization safety questions (Peter Veentjer)


----------------------------------------------------------------------

Message: 1
Date: Wed, 26 Sep 2018 07:34:03 +0300
From: Peter Veentjer <[hidden email]>
To: "[hidden email]"
        <[hidden email]>
Subject: [concurrency-interest] initialization safety questions
Message-ID:
        <CAGuAWdC+5A1CQ=QvHruBKWxo5iX=[hidden email]>
Content-Type: text/plain; charset="utf-8"

I'm studying the topic of initialization safety and want to make sure my
understanding is correct.

The following object doesn't provide initialization safety since none of
the fields are final

    class Foo_1{
        private int f1;
        private int f2;

        public Foo_1(){
            f1=1;
            f2=2;
        }
    }

Foo_2 will provide initialization safety because all the fields are final.

    class Foo_2{
        private final int f1;
        private final int f2;

        public Foo_2(){
            f2=2;
            f1=1;
        }
    }

Also Foo_3 is broken. f1 has no issues, but f2 is not final therefor
another thread could observe a Foo_3 instance with f2 not being initialized.

    class Foo_3{
        private final int f1;
        private int f2;

        public Foo_3(){
            f1=1;
            f2=2;
        }
    }

The broken nature of the Foo_3 example is mentioned here:
https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight

The question is about the following:

class Foo_4{
        private int f1;
        private final int f2;

        public Foo_4(){
            f1=1;
            f2=2;
        }
    }

If I understand the JMM correctly then this example is broken as well.
Initially I got confused by a excellent post from Shiplev:
https://shipilev.net/blog/2014/safe-public-construction/#_safe_initialization
where he states that if any field is final (and the reference doesn't
escape), safe initialization works. But he is referring to how it actually
is implemented; not about the specification.

So is it correct to say that Foo_4 is doesn't support safe initialization?

If f2 would be made volatile, then the object is supporting safe
initialization because in this case the f1=1 can't jump after the f2=2.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180926/706aeb09/attachment-0001.html>

------------------------------

Subject: Digest Footer

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


------------------------------

End of Concurrency-interest Digest, Vol 163, Issue 21
*****************************************************

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

Re: initialization safety questions

JSR166 Concurrency mailing list
In reply to this post by JSR166 Concurrency mailing list


On Tue, Sep 25, 2018 at 10:02 PM Peter Veentjer via Concurrency-interest <[hidden email]> wrote:
...
The question is about the following:

class Foo_4{
        private int f1;
        private final int f2;

        public Foo_4(){
            f1=1;
            f2=2;
        }
    }

If I understand the JMM correctly then this example is broken as well. Initially I got confused by a excellent post from Shiplev: https://shipilev.net/blog/2014/safe-public-construction/#_safe_initialization where he states that if any field is final (and the reference doesn't escape), safe initialization works. But he is referring to how it actually is implemented; not about the specification.

So is it correct to say that Foo_4 is doesn't support safe initialization?

Yes. And there's a fundamental reason I think you would not want to rely on the generated fence for non-final fields, even if the spec somehow guaranteed it's there.

On some architectures, it really is only a StoreStore fence. This means the fence, given the standard implementation with a fence after the constructor, will ensure that  a Foo_4 user will see f1 initialized. However the assert in the following slightly modified example can still fail if the client modifies f1:

class Foo_4{
        private int f1;
        private final int f2;

        public Foo_4(){
            f1=1;
            assert f1 == 1; // read can be reordered with end of constructor; may see later write
            f2=2;
        }
  }

In the final field case, f1 can't change, and this all makes a lot more sense.

Hans

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