转自:
在java的多线程中,多个线程同时运行,如涉及共享资源的访问(变量,数组,对象,数据库,webService,文件)等,则会出现相应的写操作时,其结果同我们的预期不同,我们将这称之为“线程不安全”,
下文将演示线程不安全的代码
public class TestClass { protected long count = 0; public void add(long value){ this.count = this.count + value; } }
当线程A和B同时运行同一个TestClass的实例对象中的add()方法,此时操作系统可能进行切换操作, 则会出现以下的效果:
cpu运行顺序 this.count = 0; 线程A:读取 this.count 到一个寄存器 (0) 线程B:读取 this.count 到一个寄存器 (0) 线程B:将寄存器的值加2 线程B:回写寄存器值(2)到内存. this.count 现在等于 2 线程A:将寄存器的值加3 线程A:回写寄存器值(3)到内存. this.count 现在等于 3
理论上上述线程得到的结果应该为5, 但是他实际运行情况,其结果为3
竞态条件&临界区
当两个线程竞争同一资源时,
当对资源的访问顺序有一定限制,我们将其称之为"竞态条件" 导致竞态条件发生的代码区称作"临界区"
例子中的add()方法就是一个临界区,它会产生竞态条件,所以在并发编程中,我们需特别关注其条件