Java安全线程判断

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014730165/article/details/81982470

1. 概述

通俗的讲,java多线程本质上就是管理状态的访问,而通常来讲这些状态是:共享的,可变的状态
状态 : 一个对象的状态就是它的数据,存储在状态变量中。比如他的实例域和静态域。
共享: 是指一个变量可以被多个线程进行访问。
可变: 变量的值在其生命周期内是可以被其他线程改变的
  无论何时,只要多余一个的线程访问给定的状态变量,而且摸个线程会写入改变量,时需要有必须需要用协调线程对改变量的访问,这就是线程的安全
  通过对Jvm线程模型进行分析可以发现,每个线程都拥有自己的工作空间,且是线程私有的。在线程执行代码的时候,对堆中的共享变量进行修改时,对其他的线程是不可知的。
  这里写图片描述

  从图中看出,线程1,线程2,同时读取主内存中的2个变量:flag,A。线程1设置flag=false,A=2,线程2设置Flag=false,A=3。然后同时写回到主内存。由于线程之间的私有性。所以最终主内存中的数可能是A=2,可能A=3。从而造成数据不一致的问题。


2.判断线程安全

java多线程判断线程是否安全,不是凭空想象,也不是肆意揣摩,而是从以下两个方面进行分析:原子性,可见性,有序性。

2.1 原子性

对共享变量的操作是不是原子操作
原子操作:计算机底层指令一次执行完成的操作,比如java的赋值操作,以及java的return操作。
非原子操作
例如:count++;
第一步:先从主内存中加载count的值到工作内存
第二步: 对count的值进行+1操作
这是两步操作,所以是非原子操作,在非原子操作的时候,中间可能会被打断。一旦操作被打断以后就可能存在脏读问题

2.2 可见性

当某一个线程对共享变量进行修改的时候,对其他线程是可见的。
线程修改后能够及时的从栈帧中刷新到堆里去.
其他线程能及时的从堆里获得最新的值. 首先需要说明的是可见性是只有基础类型才需要保证的, 因为引用类型的值保存在堆里, 这是对所有线程都可见的. 而基础类型会复制一份过来保存到栈帧的局部变量表, 需要用时直接丢进操作数栈使用, 这些数据对其他线程不见. 其次要说明的是即使没有synchronized和volatile关键词, 编译器可能也会帮你把堆里的值和栈帧的值同步, 因此有时可能不加关键词而线程之间依然保持可见的现象, 但为了保险起见至少还是加个volatile吧.

2.3 有序性

线程是不是按照代码的执行顺序进行执行操作
Java语言中有一个“先行发生”(happen—before)的规则,它是Java内存模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,其意思就是说,在发生操作B之前,操作A产生的影响都能被操作B观察到,“影响”包括修改了内存中共享变量的值、发送了消息、调用了方法等,它与时间上的先后发生基本没有太大关系。这个原则特别重要,它是判断数据是否存在竞争、线程是否安全的主要依据。
下面是Java内存模型中的八条可保证happen—before的规则,它们无需任何同步器协助就已经存在,可以在编码中直接使用。如果两个操作之间的关系不在此列,并且无法从下列规则推导出来的话,它们就没有顺序性保障,虚拟机可以对它们进行随机地重排序。
1、程序次序规则:在一个单独的线程中,按照程序代码的执行流顺序,(时间上)先执行的操作happen—before(时间上)后执行的操作。
2、管理锁定规则:一个unlock操作happen—before后面(时间上的先后顺序,下同)对同一个锁的lock操作。
3、volatile变量规则:对一个volatile变量的写操作happen—before后面对该变量的读操作。
4、线程启动规则:Thread对象的start()方法happen—before此线程的每一个动作。
5、线程终止规则:线程的所有操作都happen—before对此线程的终止检测,可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行。
6、线程中断规则:对线程interrupt()方法的调用happen—before发生于被中断线程的代码检测到中断时事件的发生。
7、对象终结规则:一个对象的初始化完成(构造函数执行结束)happen—before它的finalize()方法的开始。
8、传递性:如果操作A happen—before操作B,操作B happen—before操作C,那么可以得出A happen—before操作C。


3.Java语义层次的线程安全措施

synchronized: 具有原子性,有序性和可见性;
volatile:具有有序性和可见性

猜你喜欢

转载自blog.csdn.net/u014730165/article/details/81982470