自增操作原子性的理解

c中关于自增操作我测试了一小段代码:

 

int i = 0;

int increment(){
        int j = 0;
        return ++j;
}

void main(){
        ++i;
}
~                                                                               
~                                                             

 i是全局变量,j是局部变量,反汇编出来的代码如下:

 

increment:
        pushl   %ebp
        movl    $1, %eax
        movl    %esp, %ebp
        popl    %ebp
        ret
        .size   increment, .-increment
        .p2align 4,,15
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        addl    $1, i
        popl    %ebp
        ret

 可以看到关于自增运算的指令都是一条指令,加上一点限制:操作数是32位并且没有跨页,这是在C中;

 

下面看看java中:

 

public class increment{
        public static int i = 0;
        public static void main(String ar[]){
                increment ic = new increment();
                int j = 0;
                ic.i++;
                j++;
                System.out.println(i+" "+j);
        }
}

 我这里同样设置了类变量和局部变量,下面是javap的部分结果:

 

   7:	astore_1
   8:	iconst_0
   9:	istore_2
   10:	aload_1
   11:	pop
   12:	getstatic	#4; //Field i:I          //开始的是对i的运算
   15:	iconst_1
   16:	iadd
   17:	putstatic	#4; //Field i:I          //i运算结束
   20:	iinc	2, 1             //j运算

 可以看到java中对于局部变量和全局变量关于++操作的不一致,类变量的自增操作不是原子性的,通过getstatic ,iadd,putstatic 得出,是分别进行读,修改,写,而j的运算仅仅是一条iinc指令,局部变量是原子性的。。补充一下,不仅仅是类变量,实例变量(就算是没有声明static),它的自增操作也不是原子性的。

 

 

至于为什么java这么设计我想很简单吧,类的静态变量是所有实例进行共享,不是放在某一个方法栈中的,这个变量是这个类型的属性,对这个类变量的更改自然导致了所有实例的“状态”更改,而局部变量在方法返回之后是失去其作用域的。

 

友情链接:http://madbean.com/2003/mb2003-44/

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值