Java并发之基础理论

线程不安全分析

  对共享变量进行写操作时,原子性、可见性和有序性不能同时保障,导致线程不安全,如下图所示:
Java并发之基础理论
反过来说,如果没有共享变量,或者只存在共享变量的读操作则不会存在线程安全问题。

原子性

定义:原子性就是指对数据的操作是一个独立的、不可分割的整体。也就是说线程A操作数据的过程中,其它线程是无法进行修改的。
非原子性原因:一条操作系统指令的执行是原子性的,但是通常Java语言层面的一次操作对应多条操作系统指令。
  

可见性

定义:可见性是指某个线程更改共享变量后,其它线程可以立即读取到最新值。
不可见原因:每个线程都有自己的工作内存(即CPU的高级缓存,这么做的目的还是在于进一步缩小存储系统与CPU之间速度的差异,提高性能)。如下图所示,对于共享变量,线程每次读取的是工作内存中共享变量的副本,写入的时候也直接修改工作内存中副本的值,然后在某个时间点上再将工作内存与主内存中的值进行同步。这就会导致如果线程1对某个变量进行了修改,线程2却有可能看不到线程1对共享变量所做的修改。
Java并发之基础理论

有序性

定义:有序性是指程序执行的顺序按照代码的先后顺序执行。
产生乱序的原因:为了提高性能,编译器和处理器可能会对指令做重排序。主要分为以下三种:

  1. 编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
  2. 指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-Level Parallelism, ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。

*常见解决方案

Java并发之基础理论

参考:

  1. http://www.cnblogs.com/paddix/p/5374810.html
  2. http://cmsblogs.com/