• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Happens-before situation.

 
Ranch Hand
Posts: 58
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello.
Can someone please help me with the answer to the next question.
Right now I’m studying happens-before situations. I haven’t found in the java specification any proofs that compiler executes constructor before any method. So I assume that having a class like this:

and accessing it from the next code

method a.get() one day can return 0.
Is it true? If it’s not, why?
If it is, is there a way to reproduce this situation? I’m using JCSTRESS framework and still can’t get this result.
 
Marshal
Posts: 28263
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can't find it in the JLS because it isn't true. Consider this:



But it IS true that the constructor (and all instance initializers) will run to completion before "new B()" is complete. In other words in



the first line happens before the second line, as always in Java code, but in addition the first line doesn't complete until the B constructor returns.

I don't know where the JLS says that but if I wanted to find out I'd look for the part which discusses instance initializers and constructors.
 
Oleksii Movchan
Ranch Hand
Posts: 58
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Paul Clapham, I was obviously talking about access from other threads. I know that code in one thread is executed line by line.
My point is that there is no happens-before situation between i=1 in the constructor and getting this value using the get() method. There is just no rule for that (16.9 in the specification).
And the problem is I still can't reproduce that.
 
Paul Clapham
Marshal
Posts: 28263
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Oleksii Movchan wrote:Paul Clapham, I was obviously talking about access from other threads. I know that code in one thread is executed line by line.
My point is that there is no happens-before situation between i=1 in the constructor and getting this value using the get() method. There is just no rule for that (16.9 in the specification).
And the problem is I still can't reproduce that.



Ah, okay, I understand now. You're right, there's no rule for that either. And in fact it is possible for other threads to use an object before its constructor has completed. (This is generally considered to be a bad thing.)

But for that to happen there must be a way for some other thread to know about the partially-constructed object. This can be achieved by having the constructor pass a reference to "this" to some other object, and then doing some time-consuming process before returning. For example calling "submit(this)" on some ExecutorService. The code you posted doesn't do that, so that's why you can't reproduce that situation, but by writing code which lets "this" leak out of the constructor you should be able to reproduce it.
 
Oleksii Movchan
Ranch Hand
Posts: 58
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Paul Clapham, thank you! I was just looking for someone to tell me my assumptions aren't wrong
 
Ranch Hand
Posts: 59
6
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You don't need to leak a reference to this to get a partially constructed object. That is only true in single-threaded programs.

If you create an object, and then pass it to another thread, then there aren't any happens-before relationships between the constructor and the get method and you can see the uninitialized value.

But because you've started the thread after calling the constructor, then there is a happens-before relationship. Because a call to start() on a thread happens-before any actions in the started thread. See 17.4.5 in the JLS
 
Oleksii Movchan
Ranch Hand
Posts: 58
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sresh Rangi wrote:But because you've started the thread after calling the constructor, then there is a happens-before relationship. Because a call to start() on a thread happens-before any actions in the started thread. See 17.4.5 in the JLS



This code doesn't work either:

I mean, it works but returns -1 or 9 only.
 
Paul Clapham
Marshal
Posts: 28263
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
At line 15 there are two possibilities: either the MyClass constructor is complete, in which case you get 9, or else it isn't, in which case you get -1. There is no possibility of having getX() return anything except 4 because you always call it after the constructor has completed.
 
Oleksii Movchan
Ranch Hand
Posts: 58
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:There is no possibility of having getX() return anything except 4 because you always call it after the constructor has completed.



Is there a rule for that? As I already mentioned, I haven't found any information that constructor completes before any object's method is called.
 
Paul Clapham
Marshal
Posts: 28263
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Oleksii Movchan wrote:

Paul Clapham wrote:There is no possibility of having getX() return anything except 4 because you always call it after the constructor has completed.



Is there a rule for that? As I already mentioned, I haven't found any information that constructor completes before any object's method is called.



I'm just commenting on the code you posted. It guarantees that the constructor completes before getX() and getY() are called. This only means that you haven't produced a working example where a method is called before the constructor completes.

Let me suggest this code instead:



It also uses the "trick" of leaking information from a partially-constructed object.
 
Paul Clapham
Marshal
Posts: 28263
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But now that I look at it, it isn't going to compile because getX and getY aren't static, and you don't want to declare them static because that's not the question you want to ask.

So never mind that. Any code like yours is still going to have the feature that you need to get a reference to the object using the new operator, which will guarantee that the MyClass constructor has completed. The only way to avoid that issue is to get a reference to the object before the constructor completes, and the only possible way to do that is for the compiler to leak that reference to the outside world. In your last-posted code it could do that inside the constructor like this:

 
reply
    Bookmark Topic Watch Topic
  • New Topic