Consider this Kotlin code using AtomicInteger. From a JVM-internals standpoint, why is the `getAndIncrement()` call lock-free and correct even under heavy contention, while a plain `@Volatile var` would be wrong here?
val counter = java.util.concurrent.atomic.AtomicInteger(0)
// many threads:
repeat(1000) { counter.getAndIncrement() }