Re: Visibility of array initialization (Raph Frank)

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

Re: Visibility of array initialization (Raph Frank)

JSR166 Concurrency mailing list
Hi Raph,

JMM does not make any difference between read/write actions from/to static/non-static fields and to array elements: see "17.4.1. Shared Variables" (https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1) which says "All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements."

So when you think about read/write actions from/to array elements, treat them the same way you treat read/write actions from/to other shared variables.

Having said that, the anwser to your question "Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?" is: The second thread is allowed to print either -1 or 3 and nothing else (NPE is also not allowed).

Let's give letter names to some actions in executions of your program:

----------thread1
// array = null //_wa - an implicit write
///////////////////////of the default value,
///////////////////////which according to JMM
///////////////////////happens-before the first action
///////////////////////in every thread

// array[2] = 0 // _w0 - an implicit write
///////////////////////of the default value

int[] array = new int[] { //wa
  -1, -1,
  -1 //w(-1)
};
thread2.start();
array = new int[] { //wa'
  1, 2,
  3 //w3
};

----------thread2
System.out.println(
  array[ //ra, read array reference
    2 //r
  ]
);

<NPE> while dereferencing array is impossible.
  ra can't return null because the corresponding implicit write _wa is not allowed to be observed by read ra:
    HB(_wa, wa) and HB(wara), thus wa prevents ra from observing _wa.

<0> is not allowed to be observed.
  Because the corresponding implicit write _w0 is not allowed to be observed by read r:
    HB(_w0, w(-1)) and HB(w(-1), r), thus w(-1) prevents r from observing _w0.

<-1> is allowed to be printed
  Because the corresponding write w(-1) is allowed to be observed by read r:
    HB(w(-1), r) and there is no write wx such that (HB(w(-1), wx) and HB(wx, r)), i.e. there is no write wx preventing read r from observing write w(-1).

<3> is allowed to be printed
  Because the corresponding write w3 is allowed to be observed by read r:
    neither HB(w3, r) nor HB(r, w3).

<2> is not allowed to be printed
  Because no execution contains an action writing 2 in array[2]. I assume this was a typo and you meant <3>.

It's also worth mentioning that JMM sais "The semantics of operations other than inter-thread actions, such as reads of array lengths (§10.7), executions of checked casts (§5.5, §15.16), and invocations of virtual methods (§15.12), are not directly affected by data races. Therefore, a data race cannot cause incorrect behavior such as returning the wrong length for an array." So as Justin has already pointed out, you can treat array.length as a final field.

Regards,
Valentin
LinkedIn   GitHub   YouTube


On Sun, 12 Aug 2018 at 12:34, <[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. Re: Visibility of array initialization (Justin Sampson)
   2. Re: Visibility of array initialization (Yuval Shavit)


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

Message: 1
Date: Sun, 12 Aug 2018 17:44:11 +0000
From: Justin Sampson <[hidden email]>
To: Raph Frank <[hidden email]>,
        "[hidden email]"
        <[hidden email]>
Subject: Re: [concurrency-interest] Visibility of array initialization
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="utf-8"

The spec explicitly calls out the length of an array as being a final field, so it's always guaranteed to be seen correctly:

https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.7
https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.5

But array elements are just regular heap variables, initialized to 0 before the initializer expression is evaluated:

https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.6
https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1

So yeah, I'm pretty sure that means you could see 0's if the array isn't published safely.

Cheers,
Justin


From: Concurrency-interest <[hidden email]> on behalf of "[hidden email]" <[hidden email]>
Reply-To: Raph Frank <[hidden email]>
Date: Sunday, August 12, 2018 at 7:29 AM
To: "[hidden email]" <[hidden email]>
Subject: [concurrency-interest] Visibility of array initialization

I was wondering what are the visibility rules for array initialization.

If an array is initialized and then another thread gets access to a reference to that array, are the elements guaranteed to be at least their initial state (or could the array be all zeros)?

Thread 1
int[] array = new int[] {-1, -1, -1};
thread2.start();

......

array = new int[] {1, 2, 3};

Thread 2
System.out.println(array[2]);

Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?

The spec refers to final fields in the constructor of objects and also says that arrays referenced by final fields are visible (including elements).

" It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are. "

It doesn't give any indication of what happens when initializing raw arrays.  Does the array initialization count as a constructor?

Is the logical process that arrays are set to all zeros at time zero and then they are initialized when created?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180812/8eaa907a/attachment-0001.html>

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

Message: 2
Date: Sun, 12 Aug 2018 14:21:01 -0400
From: Yuval Shavit <[hidden email]>
To: [hidden email]
Cc: [hidden email],  "[hidden email]"
        <[hidden email]>
Subject: Re: [concurrency-interest] Visibility of array initialization
Message-ID:
        <CAE+h5-B6VpOeXiz-bgNGn=p32r-uiDhzZL5y1p+y21jE1f=[hidden email]>
Content-Type: text/plain; charset="utf-8"

I believe the value will be -1 or 2, but not 0 -- not for any special array
semantics, but because the call to Thread::start introduces a
happens-before (JLS 17.4.5).

On Sun, Aug 12, 2018 at 1:48 PM Justin Sampson via Concurrency-interest <
[hidden email]> wrote:

> The spec explicitly calls out the *length* of an array as being a final
> field, so it's always guaranteed to be seen correctly:
>
>
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.7
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.5
>
>
>
> But array elements are just regular heap variables, initialized to 0
> before the initializer expression is evaluated:
>
>
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.6
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1
>
>
>
> So yeah, I'm pretty sure that means you could see 0's if the array isn't
> published safely.
>
>
>
> Cheers,
>
> Justin
>
>
>
>
>
> *From: *Concurrency-interest <[hidden email]>
> on behalf of "[hidden email]" <
> [hidden email]>
> *Reply-To: *Raph Frank <[hidden email]>
> *Date: *Sunday, August 12, 2018 at 7:29 AM
> *To: *"[hidden email]" <
> [hidden email]>
> *Subject: *[concurrency-interest] Visibility of array initialization
>
>
>
> I was wondering what are the visibility rules for array initialization.
>
>
>
> If an array is initialized and then another thread gets access to a
> reference to that array, are the elements guaranteed to be at least their
> initial state (or could the array be all zeros)?
>
>
>
> *Thread 1*
>
> int[] array = new int[] {-1, -1, -1};
>
> thread2.start();
>
>
>
> ......
>
>
>
> array = new int[] {1, 2, 3};
>
>
>
> *Thread 2*
>
> System.out.println(array[2]);
>
>
>
> Is it possible for the 2nd thread to print zero?  Is it guaranteed to
> print -1 or 2?
>
>
>
> The spec refers to final fields in the constructor of objects and also
> says that arrays referenced by final fields are visible (including
> elements).
>
>
>
> " It will also see versions of any object or array referenced by those
> final fields that are at least as up-to-date as the final fields are. "
>
>
>
> It doesn't give any indication of what happens when initializing raw
> arrays.  Does the array initialization count as a constructor?
>
>
>
> Is the logical process that arrays are set to all zeros at time zero and
> then they are initialized when created?
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180812/89a0c6e3/attachment.html>

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

Subject: Digest Footer

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


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

End of Concurrency-interest Digest, Vol 162, Issue 8
****************************************************

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

Re: Visibility of array initialization (Raph Frank)

JSR166 Concurrency mailing list
All these responses miss the important aspect: the creation of the second array is not atomic, and it is not guaranteed that the assignment of a new reference to array to be observable after a write of 3 to array[2].

It is allowed that array = new int[3]; is observed first, and only then array[2]=3 is observed.

So, array[2] = 0 is observable.

Alex

On 12 Aug 2018, at 20:54, Valentin Kovalenko via Concurrency-interest <[hidden email]> wrote:

Hi Raph,

JMM does not make any difference between read/write actions from/to static/non-static fields and to array elements: see "17.4.1. Shared Variables" (https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1) which says "All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements."

So when you think about read/write actions from/to array elements, treat them the same way you treat read/write actions from/to other shared variables.

Having said that, the anwser to your question "Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?" is: The second thread is allowed to print either -1 or 3 and nothing else (NPE is also not allowed).

Let's give letter names to some actions in executions of your program:

----------thread1
// array = null //_wa - an implicit write
///////////////////////of the default value,
///////////////////////which according to JMM
///////////////////////happens-before the first action
///////////////////////in every thread

// array[2] = 0 // _w0 - an implicit write
///////////////////////of the default value

int[] array = new int[] { //wa
  -1, -1,
  -1 //w(-1)
};
thread2.start();
array = new int[] { //wa'
  1, 2,
  3 //w3
};

----------thread2
System.out.println(
  array[ //ra, read array reference
    2 //r
  ]
);

<NPE> while dereferencing array is impossible.
  ra can't return null because the corresponding implicit write _wa is not allowed to be observed by read ra:
    HB(_wa, wa) and HB(wara), thus wa prevents ra from observing _wa.

<0> is not allowed to be observed.
  Because the corresponding implicit write _w0 is not allowed to be observed by read r:
    HB(_w0, w(-1)) and HB(w(-1), r), thus w(-1) prevents r from observing _w0.

<-1> is allowed to be printed
  Because the corresponding write w(-1) is allowed to be observed by read r:
    HB(w(-1), r) and there is no write wx such that (HB(w(-1), wx) and HB(wx, r)), i.e. there is no write wx preventing read r from observing write w(-1).

<3> is allowed to be printed
  Because the corresponding write w3 is allowed to be observed by read r:
    neither HB(w3, r) nor HB(r, w3).

<2> is not allowed to be printed
  Because no execution contains an action writing 2 in array[2]. I assume this was a typo and you meant <3>.

It's also worth mentioning that JMM sais "The semantics of operations other than inter-thread actions, such as reads of array lengths (§10.7), executions of checked casts (§5.5, §15.16), and invocations of virtual methods (§15.12), are not directly affected by data races. Therefore, a data race cannot cause incorrect behavior such as returning the wrong length for an array." So as Justin has already pointed out, you can treat array.length as a final field.

Regards,
Valentin
LinkedIn   GitHub   YouTube


On Sun, 12 Aug 2018 at 12:34, <[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. Re: Visibility of array initialization (Justin Sampson)
   2. Re: Visibility of array initialization (Yuval Shavit)


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

Message: 1
Date: Sun, 12 Aug 2018 17:44:11 +0000
From: Justin Sampson <[hidden email]>
To: Raph Frank <[hidden email]>,
        "[hidden email]"
        <[hidden email]>
Subject: Re: [concurrency-interest] Visibility of array initialization
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="utf-8"

The spec explicitly calls out the length of an array as being a final field, so it's always guaranteed to be seen correctly:

https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.7
https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.5

But array elements are just regular heap variables, initialized to 0 before the initializer expression is evaluated:

https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.6
https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1

So yeah, I'm pretty sure that means you could see 0's if the array isn't published safely.

Cheers,
Justin


From: Concurrency-interest <[hidden email]> on behalf of "[hidden email]" <[hidden email]>
Reply-To: Raph Frank <[hidden email]>
Date: Sunday, August 12, 2018 at 7:29 AM
To: "[hidden email]" <[hidden email]>
Subject: [concurrency-interest] Visibility of array initialization

I was wondering what are the visibility rules for array initialization.

If an array is initialized and then another thread gets access to a reference to that array, are the elements guaranteed to be at least their initial state (or could the array be all zeros)?

Thread 1
int[] array = new int[] {-1, -1, -1};
thread2.start();

......

array = new int[] {1, 2, 3};

Thread 2
System.out.println(array[2]);

Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?

The spec refers to final fields in the constructor of objects and also says that arrays referenced by final fields are visible (including elements).

" It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are. "

It doesn't give any indication of what happens when initializing raw arrays.  Does the array initialization count as a constructor?

Is the logical process that arrays are set to all zeros at time zero and then they are initialized when created?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180812/8eaa907a/attachment-0001.html>

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

Message: 2
Date: Sun, 12 Aug 2018 14:21:01 -0400
From: Yuval Shavit <[hidden email]>
To: [hidden email]
Cc: [hidden email],  "[hidden email]"
        <[hidden email]>
Subject: Re: [concurrency-interest] Visibility of array initialization
Message-ID:
        <CAE+h5-B6VpOeXiz-bgNGn=p32r-uiDhzZL5y1p+y21jE1f=[hidden email]>
Content-Type: text/plain; charset="utf-8"

I believe the value will be -1 or 2, but not 0 -- not for any special array
semantics, but because the call to Thread::start introduces a
happens-before (JLS 17.4.5).

On Sun, Aug 12, 2018 at 1:48 PM Justin Sampson via Concurrency-interest <
[hidden email]> wrote:

> The spec explicitly calls out the *length* of an array as being a final
> field, so it's always guaranteed to be seen correctly:
>
>
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.7
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.5
>
>
>
> But array elements are just regular heap variables, initialized to 0
> before the initializer expression is evaluated:
>
>
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.6
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1
>
>
>
> So yeah, I'm pretty sure that means you could see 0's if the array isn't
> published safely.
>
>
>
> Cheers,
>
> Justin
>
>
>
>
>
> *From: *Concurrency-interest <[hidden email]>
> on behalf of "[hidden email]" <
> [hidden email]>
> *Reply-To: *Raph Frank <[hidden email]>
> *Date: *Sunday, August 12, 2018 at 7:29 AM
> *To: *"[hidden email]" <
> [hidden email]>
> *Subject: *[concurrency-interest] Visibility of array initialization
>
>
>
> I was wondering what are the visibility rules for array initialization.
>
>
>
> If an array is initialized and then another thread gets access to a
> reference to that array, are the elements guaranteed to be at least their
> initial state (or could the array be all zeros)?
>
>
>
> *Thread 1*
>
> int[] array = new int[] {-1, -1, -1};
>
> thread2.start();
>
>
>
> ......
>
>
>
> array = new int[] {1, 2, 3};
>
>
>
> *Thread 2*
>
> System.out.println(array[2]);
>
>
>
> Is it possible for the 2nd thread to print zero?  Is it guaranteed to
> print -1 or 2?
>
>
>
> The spec refers to final fields in the constructor of objects and also
> says that arrays referenced by final fields are visible (including
> elements).
>
>
>
> " It will also see versions of any object or array referenced by those
> final fields that are at least as up-to-date as the final fields are. "
>
>
>
> It doesn't give any indication of what happens when initializing raw
> arrays.  Does the array initialization count as a constructor?
>
>
>
> Is the logical process that arrays are set to all zeros at time zero and
> then they are initialized when created?
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180812/89a0c6e3/attachment.html>

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

Subject: Digest Footer

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


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

End of Concurrency-interest Digest, Vol 162, Issue 8
****************************************************
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


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

Re: Visibility of array initialization (Raph Frank)

JSR166 Concurrency mailing list
Alex,

You are 100% right, thanks for pointing this out!

Regards,
Valentin
LinkedIn   GitHub   YouTube


On Sun, 12 Aug 2018 at 14:30, Alex Otenko <[hidden email]> wrote:
All these responses miss the important aspect: the creation of the second array is not atomic, and it is not guaranteed that the assignment of a new reference to array to be observable after a write of 3 to array[2].

It is allowed that array = new int[3]; is observed first, and only then array[2]=3 is observed.

So, array[2] = 0 is observable.

Alex

On 12 Aug 2018, at 20:54, Valentin Kovalenko via Concurrency-interest <[hidden email]> wrote:

Hi Raph,

JMM does not make any difference between read/write actions from/to static/non-static fields and to array elements: see "17.4.1. Shared Variables" (https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1) which says "All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements."

So when you think about read/write actions from/to array elements, treat them the same way you treat read/write actions from/to other shared variables.

Having said that, the anwser to your question "Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?" is: The second thread is allowed to print either -1 or 3 and nothing else (NPE is also not allowed).

Let's give letter names to some actions in executions of your program:

----------thread1
// array = null //_wa - an implicit write
///////////////////////of the default value,
///////////////////////which according to JMM
///////////////////////happens-before the first action
///////////////////////in every thread

// array[2] = 0 // _w0 - an implicit write
///////////////////////of the default value

int[] array = new int[] { //wa
  -1, -1,
  -1 //w(-1)
};
thread2.start();
array = new int[] { //wa'
  1, 2,
  3 //w3
};

----------thread2
System.out.println(
  array[ //ra, read array reference
    2 //r
  ]
);

<NPE> while dereferencing array is impossible.
  ra can't return null because the corresponding implicit write _wa is not allowed to be observed by read ra:
    HB(_wa, wa) and HB(wara), thus wa prevents ra from observing _wa.

<0> is not allowed to be observed.
  Because the corresponding implicit write _w0 is not allowed to be observed by read r:
    HB(_w0, w(-1)) and HB(w(-1), r), thus w(-1) prevents r from observing _w0.

<-1> is allowed to be printed
  Because the corresponding write w(-1) is allowed to be observed by read r:
    HB(w(-1), r) and there is no write wx such that (HB(w(-1), wx) and HB(wx, r)), i.e. there is no write wx preventing read r from observing write w(-1).

<3> is allowed to be printed
  Because the corresponding write w3 is allowed to be observed by read r:
    neither HB(w3, r) nor HB(r, w3).

<2> is not allowed to be printed
  Because no execution contains an action writing 2 in array[2]. I assume this was a typo and you meant <3>.

It's also worth mentioning that JMM sais "The semantics of operations other than inter-thread actions, such as reads of array lengths (§10.7), executions of checked casts (§5.5, §15.16), and invocations of virtual methods (§15.12), are not directly affected by data races. Therefore, a data race cannot cause incorrect behavior such as returning the wrong length for an array." So as Justin has already pointed out, you can treat array.length as a final field.

Regards,
Valentin
LinkedIn   GitHub   YouTube


On Sun, 12 Aug 2018 at 12:34, <[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. Re: Visibility of array initialization (Justin Sampson)
   2. Re: Visibility of array initialization (Yuval Shavit)


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

Message: 1
Date: Sun, 12 Aug 2018 17:44:11 +0000
From: Justin Sampson <[hidden email]>
To: Raph Frank <[hidden email]>,
        "[hidden email]"
        <[hidden email]>
Subject: Re: [concurrency-interest] Visibility of array initialization
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="utf-8"

The spec explicitly calls out the length of an array as being a final field, so it's always guaranteed to be seen correctly:

https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.7
https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.5

But array elements are just regular heap variables, initialized to 0 before the initializer expression is evaluated:

https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.6
https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1

So yeah, I'm pretty sure that means you could see 0's if the array isn't published safely.

Cheers,
Justin


From: Concurrency-interest <[hidden email]> on behalf of "[hidden email]" <[hidden email]>
Reply-To: Raph Frank <[hidden email]>
Date: Sunday, August 12, 2018 at 7:29 AM
To: "[hidden email]" <[hidden email]>
Subject: [concurrency-interest] Visibility of array initialization

I was wondering what are the visibility rules for array initialization.

If an array is initialized and then another thread gets access to a reference to that array, are the elements guaranteed to be at least their initial state (or could the array be all zeros)?

Thread 1
int[] array = new int[] {-1, -1, -1};
thread2.start();

......

array = new int[] {1, 2, 3};

Thread 2
System.out.println(array[2]);

Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?

The spec refers to final fields in the constructor of objects and also says that arrays referenced by final fields are visible (including elements).

" It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are. "

It doesn't give any indication of what happens when initializing raw arrays.  Does the array initialization count as a constructor?

Is the logical process that arrays are set to all zeros at time zero and then they are initialized when created?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180812/8eaa907a/attachment-0001.html>

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

Message: 2
Date: Sun, 12 Aug 2018 14:21:01 -0400
From: Yuval Shavit <[hidden email]>
To: [hidden email]
Cc: [hidden email],  "[hidden email]"
        <[hidden email]>
Subject: Re: [concurrency-interest] Visibility of array initialization
Message-ID:
        <CAE+h5-B6VpOeXiz-bgNGn=p32r-uiDhzZL5y1p+y21jE1f=[hidden email]>
Content-Type: text/plain; charset="utf-8"

I believe the value will be -1 or 2, but not 0 -- not for any special array
semantics, but because the call to Thread::start introduces a
happens-before (JLS 17.4.5).

On Sun, Aug 12, 2018 at 1:48 PM Justin Sampson via Concurrency-interest <
[hidden email]> wrote:

> The spec explicitly calls out the *length* of an array as being a final
> field, so it's always guaranteed to be seen correctly:
>
>
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.7
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.5
>
>
>
> But array elements are just regular heap variables, initialized to 0
> before the initializer expression is evaluated:
>
>
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-10.html#jls-10.6
>
> https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.1
>
>
>
> So yeah, I'm pretty sure that means you could see 0's if the array isn't
> published safely.
>
>
>
> Cheers,
>
> Justin
>
>
>
>
>
> *From: *Concurrency-interest <[hidden email]>
> on behalf of "[hidden email]" <
> [hidden email]>
> *Reply-To: *Raph Frank <[hidden email]>
> *Date: *Sunday, August 12, 2018 at 7:29 AM
> *To: *"[hidden email]" <
> [hidden email]>
> *Subject: *[concurrency-interest] Visibility of array initialization
>
>
>
> I was wondering what are the visibility rules for array initialization.
>
>
>
> If an array is initialized and then another thread gets access to a
> reference to that array, are the elements guaranteed to be at least their
> initial state (or could the array be all zeros)?
>
>
>
> *Thread 1*
>
> int[] array = new int[] {-1, -1, -1};
>
> thread2.start();
>
>
>
> ......
>
>
>
> array = new int[] {1, 2, 3};
>
>
>
> *Thread 2*
>
> System.out.println(array[2]);
>
>
>
> Is it possible for the 2nd thread to print zero?  Is it guaranteed to
> print -1 or 2?
>
>
>
> The spec refers to final fields in the constructor of objects and also
> says that arrays referenced by final fields are visible (including
> elements).
>
>
>
> " It will also see versions of any object or array referenced by those
> final fields that are at least as up-to-date as the final fields are. "
>
>
>
> It doesn't give any indication of what happens when initializing raw
> arrays.  Does the array initialization count as a constructor?
>
>
>
> Is the logical process that arrays are set to all zeros at time zero and
> then they are initialized when created?
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180812/89a0c6e3/attachment.html>

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

Subject: Digest Footer

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


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

End of Concurrency-interest Digest, Vol 162, Issue 8
****************************************************
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


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

Re: Visibility of array initialization (Raph Frank)

JSR166 Concurrency mailing list
In reply to this post by JSR166 Concurrency mailing list
Valentin>Having said that, the anwser to your question "Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?" is: The second thread is allowed to print either -1 or 3 and nothing else (NPE is also not allowed).

I would argue there.

TL;DR: -1, 0, 3 are allowed. NPE is forbidden.


1) NPE is not allowed (since there's only one write of null to `array` field which is implicit write of default value).

2) 0 is also allowed since Thread 2 could see updated value of `array` (that is it could see the reference to the array that was set after the thread started).
Apparently, there are "implicit writes of 0 values of the elements in the new array", and nothing prevents Thread 2 from observing those writes.


JLS6> and each component of the array is initialized to its default value (§4.12.5).

In other words, new int[] {1, 2, 3}; does not mean the array is created "atomically".
It is equivalent to the   x=new int[3]; x[0]=1; x[1]=2; x[2]=3;
Obviously that can cause Thread2 to observe 0 as well.


Vladimir


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

Re: Visibility of array initialization (Raph Frank)

JSR166 Concurrency mailing list
Vladimir,

Yes, I have missed this part :( Thank you! This is a good reminder of how careful one should be when thinking about which writes are there, and which writes are allowed to be observed.

Regards,
Valentin
LinkedIn   GitHub   YouTube


On Sun, 12 Aug 2018 at 14:36, Vladimir Sitnikov <[hidden email]> wrote:
Valentin>Having said that, the anwser to your question "Is it possible for the 2nd thread to print zero?  Is it guaranteed to print -1 or 2?" is: The second thread is allowed to print either -1 or 3 and nothing else (NPE is also not allowed).

I would argue there.

TL;DR: -1, 0, 3 are allowed. NPE is forbidden.


1) NPE is not allowed (since there's only one write of null to `array` field which is implicit write of default value).

2) 0 is also allowed since Thread 2 could see updated value of `array` (that is it could see the reference to the array that was set after the thread started).
Apparently, there are "implicit writes of 0 values of the elements in the new array", and nothing prevents Thread 2 from observing those writes.


JLS6> and each component of the array is initialized to its default value (§4.12.5).

In other words, new int[] {1, 2, 3}; does not mean the array is created "atomically".
It is equivalent to the   x=new int[3]; x[0]=1; x[1]=2; x[2]=3;
Obviously that can cause Thread2 to observe 0 as well.


Vladimir


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