Java atomic operations

Is it correct to divide the following statements:

int v = ++j; 

as:

  • read the value of j (atomic);
  • increment by 1 value counted (NON atomic possible interference with another thread);
  • write the result of adding to i (Atomic);
  • write i in v (atomic)
+4
source share
4 answers

Yes, int (or smaller data types) read / write / arithmetic operations are atomic. References (read / write) are also atomic, regardless of whether they are 32-bit or 64-bit.

However, operations with 64-bit long and double may not be atomic.

JLS 17.7 Non-atomic processing of double and long

In some implementations, it may be convenient to split one write action into a 64-bit long or double value into two write actions with adjacent 32-bit values. For efficiency, this behavior is implementation specific; Java virtual machines can write in the long and double values โ€‹โ€‹atomically or in two parts.

For the purpose of the memory model of the Java programming language, a single record in a non- volatile long or double value is considered as two separate records: one for each 32-bit half. This can lead to a situation where the stream sees the first 32 bits of a 64-bit value from one record and the second 32 bits from another record. Writing and reading volatile long and double values โ€‹โ€‹are always atomic. Writes and reads of links are always atomic, regardless of whether they are implemented as 32 or 64-bit values.

VM developers are advised to avoid splitting their 64-bit values โ€‹โ€‹where possible. Programmers are advised to declare common 64-bit values โ€‹โ€‹as volatile or to synchronize their programs correctly in order to avoid possible complications.

Please note that neither the pre-nor operators nor the post-increment / decrement are themselves atomic, not even int or byte : read / write / arithmetic operations take place in clearly separate steps.

see also

+8
source

To close. Step 2 is atomic. In this case, j must be one of byte , char , short or int , and each of them can be loaded and saved atomically.

Once the value has been loaded into the hardware register, it should not be possible for another thread to interfere with it. There is probably something in JLS about the atomicity of primitive operations ... but I cannot notice it.

+1
source

Yes, your assumption is correct. Incrementing int leads to three steps (thus it is not atomic), assigning it is another step. Below is the bytecode:

 .. istore_1 iinc 1, 1 iload_1 istore_2 .. 
+1
source

I would use AtomicInteger

 AtomicInteger j; // do init int v = j.incrementAndGet(); 

A quick scan with JAD shows the following byte code for instructions:

  int j = 0; // 0 0:iconst_0 // 1 1:istore_1 int v = ++j; // 2 2:iinc 1 1 // 3 5:iload_1 // 4 6:istore_2 
0
source

All Articles