如果线程1在执行第一条代码的时候,线程2访问i变量,这个时候,i的值还没有变化,还是原来的值,所以是不安全的。 从更底层的角度讲,主要是因为i++这个操作不是原子性的,这个会编译成i= i +1; 所以会出现多线程访问冲突问题。volatile虽然可以保证多线程对修改可见,但代码中用到了 i++, 主要是i++不是原子性...
i++并不是线程安全的。 i++这个操作实际上包含了三个步骤:读取i的值,对i加1,将新值写回到i。在多线程环境下,这三个步骤可能会被打断,例如,一个线程在读取了i的值并且加1之后,但还没来得及将新值写回i,这时另一个线程也来读取i的值并加1,然后写回i,这时第一个线程再将它计算的值写回i,就会覆盖掉第...
由于线程共享栈区,不共享堆区和全局区,所以当且仅当 i 位于栈上是安全的,反之不安全(++i 也同理). 因为如果是全局变量的话,同一进程中的不同线程都有可能访问到。对于读值,+1,写值这三步操作,在这三步任何之间都可能会有 CPU 调度产生,造成 i 的值被修改,造成脏读脏写。 其实,最核心的就是这个 +1...
由于线程共享栈区,不共享堆区和全局区,所以当且仅当 i 位于栈上是安全的,反之不安全。 2. AtomicInteger 和 各种 Lock 都可以确保线程安全。AtomicInteger 的效率高是因为它是互斥区非常小,只有一条指令,而 Lock 的互斥区是拿锁到放锁之间的区域,至少三条指令。
i++是不安全的,因为java在操作i++的时候,是分步骤做的,可以理解为:tp = i;tp2 = i+1;i=tp2;如果线程1在执行第一条代码的时候,线程2访问i变量,这个时候,i的值还没有变化,还是原来的值,所以是不安全的。
线程不安全,是指不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 其实小白话就是 : 多线程操作的时候 ,容易出现与我们预想不一致的结果。 就比如说,你做好准备 接我两拳。 本来你以为 我是打完一拳再打一拳。 结果我直接一招双龙出海,两只手一起打你, 你顶得住么?(你根本...
既然结果不能保证一致性,肯定是线程不安全的。这是一条Java语句,那我就从Java内存模型上来解释吧。 如果一开始i等于0,那么java内存模型如图: i得到最大值200很容易理解 线程A首先对i变量进行100次++操作,JMM如下 线程B再对i变量进行100次++操作,JMM如下 i得到最大值很容易理解,那么什么情况i是得到最小值2呢?
2、为什么i++运算不是线程安全的? 3、什么情况下会出现线程安全问题? 4、什么是临界区资源、临界区代码、竞态条件? 5、Synchronized 对象锁? 6、Synchronized 同步方法? 7、Synchronized 同步方法的锁对象? 8、Synchronized 静态同步方法的锁对象? 9、如果同步方法/块 内的线程抛出异常,则对象锁自动释放? 10、 ...
我们称这种情况下的程序或库是**线程安全**的。简单来说,就是在并发环境下保证数据不会出现意外修改...
原话是这样的,基本数据类型的赋值是原子性操作。这里还要排除long和double,或者标明64bit操作系统。因为long和double类型是8字节,而低位操作系统(32bit)单次内存的存储结构最大只能存储4个字节,所以每次操作都要分两次进行,也就是非原子性操作。那int类型的i++为什么还有线程安全问题(推测了问题真正...