3 ms·
I don't program much in java, but I would have thought that the problem was in the assignment of the new Point to currentPost, not the construction of the new P
by casperc 13y ago
I don't program much in java, but I would have thought that the problem was in the assignment of the new Point to currentPost, not the construction of the new Point.
I would have thought that the order of operations would be:
1) Read value from currentPos.x and add 1. Do same for y.
2) Pass values to constructor
3) Construct the new object
3a) init values with 0
3b) assign new values to x and y
4) Assign the newly constructed object's pointer to currentPos.
I thought that the problem lay in 4 where you might read a partial update of the pointer, possibly giving weird results. Is he saying that it might get assigned first and then constructed afterwards?
- windust 13y agoYou're assuming that the code is executing in the way you read it, which is false. With the advent of branch prediction and Instruction reordering in CPUS (to gain performance), a CPU have the liberty of reordering operations for efficiency (http://en.wikipedia.org/wiki/Out-of-order_execution http://en.wikipedia.org/wiki/Out-of-order_execution) EXCEPT when there are memory barriers (or explicit synchronization instructions). With a multi-core processor things get even more complex, as you have cache locality (a thread reading the point value might be hitting the CPU cache and not main memory). If the thread happens to be executing on a different core than the assigning thread, disaster ensues.
- EdiX 13y ago> I thought that the problem lay in 4 where you might read a partial update of the pointer, possibly giving weird results. Is he saying that it might get assigned first and then constructed afterwards? Yes. In some versions of java the code: x = new X() results in assigning to x a reference to a new uninitialized object X and then a call to the constructor. Reference assignment in java is always atomic, it is guaranteed by the memory model.
- barrkel 13y agoNo. x = new X() should not make x assigned such that it is visible inside the constructor of X. The behaviour in the post can only been seen with concurrency. The issue here is the lack of a write barrier at the point of publishing the reference to the newly constructed object, and the lack of a read barrier at the point of reading the reference to the newly constructed object. You want to stop both writes moving forward in time (the writes in the constructor happening after the write that publishes the object) and reads moving backwards in time (the reads on the other thread reading the old values of the constructed object, rather than the initialized values - may be caused by e.g. satisfying the read from per-CPU cache). Java's volatile acts both ways; writes are write barriers and reads are read barriers.