首先明确,笔者在这不讨论"+"号做为字符串拼接的做用,而是做为运算符产生的问题。
也就是说下在Java中 i+1 、 i++ 、 ++i之间的区别java
i++ 和 ++i 明显区别于 i+1 的是前二者的i的值都增长了。
若是给 i+1 赋值的话,又存在两种状况:安全
int x=0;
int y=0;
while(x<10){
x = x+1;
System.out.print(x+" ");
}
System.out.println();
while(y<10){
++y;
System.out.print(y+" ");
}
复制代码
运算结果:bash
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
复制代码
在循环中来讲,上面第一种状况的返回值的大小等价于 ++i ;第二种状况中 i 是不变的。多线程
这二者要放到一块儿讨论。
通俗来说,其中 i++ 是先赋值后运算; ++i 是先运算后赋值,但他们在Java中都只能做为右值使用,不能做为左值。并发
左值是对应(refer to)内存中有肯定存储地址的对象的表达式的值,而右值是全部不是左值的表达式的值。
这两个在循环中的代码:ui
int i = 0;
int j = 0;
while(i<6){
int x = i++;
System.out.print(x+""+i+" ");
}
System.out.println();
while(j<6){
int y = ++j;
System.out.print(y+""+j+" ");
}
复制代码
结果:atom
01 12 23 34 45 56
11 22 33 44 55 66
复制代码
他们在寄存器中的运算过程用代码表示以下:spa
i++ >>>
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_2
7: return
++i >>>
0: iconst_0
1: istore_1
2: iinc 1, 1
5: iload_1
6: istore_2
7: return
复制代码
也就是说i++ 运算中,栈顶值是 0 ,++i 运算中栈顶值是 1。线程
总的来讲,在 i++ 与 ++i 这两个运算中i都是增长了的,只是 i++ 返回的值是增长前的值, ++i 返回的值是增长后的值code
1. 有一个骚操做 i = i++; while循环中出现这个基本就死循环了
int i = 0;
while (i < 2) {
i = i++;
System.out.println(i);
}
复制代码
结果就是一堆 0,你能够本身想一想是为何。
对了若是你的输出语句不换行控制台是打印不出消息的,由于结果长度超出限制了。
2.多线程中的并发问题
i++ 与 ++i 都并不是线程安全的运算,由于这二者都不是原子操做。
到这有人可能会想,是否能够用volatile关键字修饰来保证线程安全呢?答案是不能。由于volatile只能保证可见性,不能保证原子性。
那么到底怎么在多线程中保证这二者的线程安全呢?有两个办法: