@kordirko It works, thank you! Btw I hadn't use a volatile before
You are welcome, I am glad I could help.
However, since you are using threads, you need to know some facts about volatile and not volatile variables and review your code to avoid another subtle synchronization pitfalls.
From the Java specification:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.7
17.7. Non-Atomic Treatment of double and long
For the purposes of the Java programming language memory model, a
single write to a non-volatile long or double value is treated as two
separate writes: one to each 32-bit half. This can result in a
situation where a thread sees the first 32 bits of a 64-bit value from
one write, and the second 32 bits from another write.
Writes and reads of volatile long and double values are always atomic.
Writes to and reads of references are always atomic, regardless of
whether they are implemented as 32-bit or 64-bit values.
The above means, that if you share some long and double non-volatile variables between two or more threads, then even if the code seems to work correctly, from time to time the code will fail, because one thread will see only a partial updated value of the variable.
You have to declare them as volatile.
And from one answer on Stack Overflow:
Volatile variable in Java
When is volatile needed ?
When multiple threads using the same variable, each thread will have
its own copy of the local cache for that variable. So, when it's
updating the value, it is actually updated in the local cache not in
the main variable memory. The other thread which is using the same
variable doesn't know anything about the values changed by the another
thread. To avoid this problem, if you declare a variable as volatile,
then it will not be stored in the local cache. Whenever thread are
updating the values, it is updated to the main memory. So, other
threads can access the updated value.
The above explains why your code worked fine when //System.out.println(getPosition().x());
was uncommented, and failed when this line was commented.
The volatile keyword simply means to the compiler "I am going to share this field between many threads, please synchronize access to this field and always retrieve it's actual value directly from the memory".
The field x
was not declared as volatile, so the compiler didn't synchronize it, and optimized this fragment of code in such a way, that a value of the variable wasn't retrieved directly from the memory, but from a local cache (most likely stored in processor's registers). The thread didn't know that another thread updated a value of this field in the memory, it saw only a value from the local cache.
When a call to println
was uncommented, then the value of x
was flusched from the cache by this call, and retrieved directly from the memory after the call had finished - in this way the thread saw the updated value.