好习惯要坚持,这是我第二篇博文,任务略重,但是要坚持努力!!!
1.竞争条件
首先,我们回顾一下《Java核心技术卷》里讲到的多线程的“竞争条件”。由于各线程访问数据的次序,可能会产生讹误的现象,这样一个情况通常称为“竞争条件”。
那么,讹误具体是怎么产生的呢?本质上,是由于操作的非原子性。比如,假定两个线程同时执行指令 account[to] += amount;该指令可能会被处理如下:
1)将account[to]加载到寄存器。
2)增加amount[to]。
3)将结果写回account[to]。
现在,假定第一个线程执行步骤1和2,然后,它被剥夺了运行权。假定第二个线程被唤醒并修改了accounts数组中的同一项。然后,第1个线程被唤醒并完成第3步。这样,这一动作擦去了第二个线程所做的更新。于是,总金额不再正确。
---------------------------------------------我是分割线---------------------------------------------------------------------------------------------
好,我们再从java的内存模型来深层次讲讲“讹误”,这里有个概念叫做“缓存一致性”。
大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。
也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。举个简单的例子,比如下面的这段代码:
i = i + 1;

