i++
is probably not atomic in Java because atomicity is a special requirement which is not present in the majority of the uses of i++
. That requirement has a significant overhead: there is a large cost in making an increment operation atomic; it involves synchronization at both the software and hardware levels that need not be present in an ordinary increment.
You could make the argument that i++
should have been designed and documented as specifically performing an atomic increment, so that a non-atomic increment is performed using i = i + 1
. However, this would break the "cultural compatibility" between Java, and C and C++. As well, it would take away a convenient notation which programmers familiar with C-like languages take for granted, giving it a special meaning that applies only in limited circumstances.
Basic C or C++ code like for (i = 0; i < LIMIT; i++)
would translate into Java as for (i = 0; i < LIMIT; i = i + 1)
; because it would be inappropriate to use the atomic i++
. What's worse, programmers coming from C or other C-like languages to Java would use i++
anyway, resulting in unnecessary use of atomic instructions.
Even at the machine instruction set level, an increment type operation is usually not atomic for performance reasons. In x86, a special instruction "lock prefix" must be used to make the inc
instruction atomic: for the same reasons as above. If inc
were always atomic, it would never be used when a non-atomic inc is required; programmers and compilers would generate code that loads, adds 1 and stores, because it would be way faster.
In some instruction set architectures, there is no atomic inc
or perhaps no inc
at all; to do an atomic inc on MIPS, you have to write a software loop which uses the ll
and sc
: load-linked, and store-conditional. Load-linked reads the word, and store-conditional stores the new value if the word has not changed, or else it fails (which is detected and causes a re-try).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…