1.结论:
不是安全的,不是原子的
2.原因:
2.1 不是原子性的原因:
一个线程将一个全局变量--(减减)时候,需要以下几个步骤
第一步:将全局变量读到cpu的寄存器中,
第二步:cpu将全局变量进行减减操作,
第三步:将减完的值传给内存。
2.2 对一个全局变量进行多线程并发 -- 或者 ++ 操作不是安全的原因:
假设情景:
原来的数据是100,对多线程(有线程1和线程2)对100进行减减操作。
原来的数据是100,线程操作内容是--,线程1是只--了一次,正准备把cpu中的数据传到内存中,就被线城2顶了上来,此时从内存中加载到cpu的从100减到了99,线程1把此时cpu中的99拿到自己的tcb中,当做自己上下文(99),
线程2多次--(进行了1.2.3步骤),减到了10,最后把cpu中的数据(10)加载到了内存中。
线程1此时顶了回来,恢复了上下文(99),把自己的上下文(99)加载到了cpu里,最后把值(99)返回到了内存中.
导致线程二做了无用功。
3.扩展
判断的时候,也会经历将值从内存中传到cpu,由cpu进行判断,再讲cpu中的值传入到内存中。
将--代码和判断代码放在一块,挑战一下:
3.2代码示例:
全局变量是: ticket
3.2. 难点解析
第一次判断时候进来是1,返回到内存中也是1,第一次的减减的时候,返回到内存的是0。第二次判断的时候进来的时候虽然也是1,但是减减的时候会重新从内存中读取数据,此时内存中的数据是0,减减操作会使其成为负数。
4.线程将共享数据加载到cpu的本质:
把数据内容,变成自己的上下文——以拷贝的方式,单独给自己那一份。