Reputation: 3965
I want to know if calculation of the function value and assignment of the result to a variable is an atomic operation in Java.
For example:
I have a thread-safe priority queue q
. In q
I save elements, and each element has a rank
according to which it is placed in the queue. In addition I have a shared variable topRank
that should always contain the rank of the topmost element in q
. The following code is executed in parallel by number of threads:
element = q.remove(); // do something with element
topRank = q.peek();
could it happen that threadA would remove one elements from q
and calculate value of q.peek()
and just before assigning it to topRank
would be interrupted by threadB, then threadB would remove one more element from q
and update topRank
. And then threadA would resume to assignment of incorrect value to the topRank
.
A link to official literature would be very appreciated.
Thanks.
Upvotes: 2
Views: 305
Reputation: 310883
Calculation of a function value cannot possibly be atomic. The function could run for years before returning a value.
Upvotes: 0
Reputation: 24885
1) I do not think that there are atomic operations, unless you protect them (synchronization and other technics).
2) That said, it does not apply to your example.
In your example you have.
a) Call q.remove()
b) q.remove()
does its work (thread safe or not).
c) q.remove()
returns a result
d) The result is assigned to element
(this is the assignment!! all of before was just calculating the value to assign.)
So, it is not only if assignment (the last step in your operation) is atomic or not, you need to ensure that q.remove() is atomic too. And I assure you that it is not.
As it is not thread safe, if you want to avoid concurrent access you should synchronize the entire block.
EDIT answering the authors comment.
So what you are asking is if somehow q.peek()
will return an elelent but another one will end in topRank
due to other thread messing with it, isnt'it?
Unless topRank
is shared by the different threads, it is not possible:
a) q.peek()
runs its logic
b) the return value of q.peek()
is copied (stored in the stack, back to expression that called q.peek()
)
c) q.peek()
exits. Only now other instances can access the synchronized section to change q.state, but the return value is already copied in the stack.
d) The copy in the stack is assigned to topRank
Upvotes: 0
Reputation: 86774
The short answer is that these operations are NOT atomic and you need to write the synchronization into your code. This is a HUGE topic and there is a lot to learn about writing thread-safe programs. Google for "java thread safety" and "java multithreading".
Upvotes: 4
Reputation: 231113
Thread-safety only refers to the operation within the remove()
or peek()
calls. Unless you take steps to block threads from racing with each other, the race with topRank
is entirely possible.
For more information, take a look at the Java synchronization tutorial.
Upvotes: 1