Visibility of array initialization

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

Visibility of array initialization

JSR166 Concurrency mailing list
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
Reply | Threaded
Open this post in threaded view
|

Re: Visibility of array initialization

JSR166 Concurrency mailing list

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
Reply | Threaded
Open this post in threaded view
|

Re: Visibility of array initialization

JSR166 Concurrency mailing list
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

_______________________________________________
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

JSR166 Concurrency mailing list


On Sun, Aug 12, 2018 at 7:21 PM, Yuval Shavit <[hidden email]> wrote:
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).

I think it could generate a zero since the 2nd array is a new array.  This is potentially zero.


On Sun, Aug 12, 2018 at 8:54 PM, Valentin Kovalenko via Concurrency-interest <[hidden email]> wrote:
Let's give letter names to some actions in executions of your program:

I tried to re-write based on your notation.

Thread 1
int[] array = new int[] {-1, -1, -1};  // INIT (Involves a W0, WE and WA but is all synced by thread2.start() anyway)

thread2.start();
// This acts as the point of forking for the 2 threads.

......

array = new int[] {1, 2, 3};
//  Based on your comments, this line can be split
//
// W0:  set all elements to zeros (time zero operation)
//
// WE:  Initialize [2] element to 3
// WA:  Set array to reference the new array


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

INIT happens before everything, since it happens before the .start() call of thread 2.

W0 happens before the System.out.println call, since it is default initialization.

WE & WA have no happens before relationship with the System.out call. 

This means that the System.out could see WE or WA.  If it doesn't see either of them, then it would see the result of W(0).

This means that 3, 0 and -1 are possible.  Is this correct?

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