i++ 和 ++i 是否为原子操作(Java基础)
非原子操作
举例:
public static int i = 0; public static volatile int count = 0; public static void main(String[] args) throws Exception { for (int j = 0; j < 10; j++) { new MyThread().start(); } while(count != 0) System.out.println(i); } public static class MyThread extends Thread { @Override public void run() { try { Thread.sleep(1000); } catch (Exception e) { } for (int j = 0; j < 100; j++) { i++; } ++count; } }
理想情况,应该输出1000,而情况并非如此。
volatile 声明的变量为"可见的",一般应用于多线程中,为共享变量,但是volatile只能保证变量可见性,不能保证它的原子性。
在Java中 ++i 或者 i++是一条语句,执行javac -encoding utf8 xxx.java 和 javap -c xxx.class 命令后,查看字节码层面上也是 iinc 1,1 这一条JVM指令。但是从底层CPU层面上,可分为3个指令操作:
1. 取数
2. 累加
3. 存储
一条指令,可以保证其原子性操作,而多条指令则是非原子性操作。
如果保证i++ 或者 ++i可以实现原子操作,则需要搭配synchronized或者J.U.C中的排他锁(如ReentrantLock等)使用。
或者采用java.util.concurrent.atomic包下的原子类,如AtomicBoolean#getAndSet(boolean value),AtomicInteger#getAndAdd(int value),
AtomicIntegerArray#getAndSet(int index, int value),AtomicLong#getAndAdd(long),AtomicLongArray#getAndAdd(int index, long value)等原子类的方法进行记录。

浙公网安备 33010602011771号