【正确答案】语句i=i++不是线程安全的。
本题中,语句i=i++的执行过程如下:先把i的值取出来放到栈顶,可以理解为引入了一个第三方变量k,此时,k的值为i,然后执行自增操作,于是i的值变为1,最后执行赋值操作i=k(自增前的值),因此,执行结束后,i的值还是0。从上面的分析可知,i=i++语句的执行过程由多个操作组成,它不是原子操作,因此,它不是线程安全的。
在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免地会用到synchronized关键字。而AtomicInteger是一个提供原子操作的Integer的类,它提供了线程安全且高效的原子操作,是线程安全的,其底层的原理是利用处理器的CAS(Compare And Swap,比较与交换,一种有名的无锁算法)操作来检测栈中的值是否被其他线程改变,如果被改变,则CAS操作失败。这种实现方法在CPU指令级别实现了原子操作,因此,它比使用synchronized来实现同步效率更高。
CAS操作过程都包含三个运算符:内存地址V、期望值A和新值B。当操作的时候,如果地址V上存放的值等于期望值A,则将地址V上的值赋为新值B,否则,不做任何操作,但是要返回原值是多少。这就要求保证比较和设(置)值这两个动作是原子性操作。系统主要利用JNI(Java Native Interface,Java本地接口)来保证这个原子操作,它利用CPU硬件支持来完成,使用硬件提供swap和test_and_set指令,单CPU下同一指令的多个指令周期不可中断,SMP(Symmetric Multi-Processing,对称多处理结构)中通过锁总线支持这两个指令的原子性。
【答案解析】