标签:原子性操作 内存 没有 方法 java内存模型 三种方式 程序 运行 被锁
Java中对基本数据类型变量的读取赋值都是原子性的,对引用类型变量的读取和赋值也是原子性。这类操作都是不可被中断的,要么执行,要么不执行。
(1) 赋值操作:x = 10;
操作是原子性。
(2) 赋值操作:y = x;
操作是非原子性。将变量x赋值给y,包含两个重要步骤:
1)执行线程从主存中读取x的值,然后将其存入当前线程的工作内存
2)在执行线程的工作内存中修改y的值为x,然后将其写入主存
两个步骤都是原子类型操作,但组合在一起就不是了
(3) 自增操作:y++;
操作是非原子性:它包含了三个重要步骤:
1)执行线程从主存中读取y的值,将其存入当前线程的工作内存
2)在执行线程工作内存中为y执行加1操作
3)将y值写回主存
多线程环境下,某线程首次读取共享变量,首先到主存中获取,存入工作内存。如果对该变量执行修改操作,则将新值写入工作内存,再刷新到主存。但是这一刷新的时间是不确定的,其他线程不知道该线程的修改操作,因此Java提供三种方式保障可见性:
Java内存模型中,允许编译器和处理器对指令进行重排序,
多线程下重排序会影响程序的正确运行,Java提供volatile、synchornized和显示锁三种方式保证有序性。
除三种方式之外,JMM本身存在有序性规则,这个规则不需要任何同步手段就能保证有序性,这个规则称为happens-before原则。若两个操作不满足happens-before原则以及由它推导出的规则,那么这两个操作就没有顺序保障,JVM或处理器可以对它们任意排序:
这一条看似是说程序按照次序执行,但虚拟机、处理器还是会对指令进行重排序,只能保障程序执行的结果与顺序执行的结果一致。多线程下无法保障正确性。
这条规则意思是,无论单线程还是多线程环境下,一个锁出于被锁定状态,那么必须先释放锁再加锁。
这条规则意思是,如果一个变量是volatile修饰的,一个线程对它进行读操作,一个线程对它进行写操作,那么写入操作肯定要先行发生于读操作。这条规则标志了线程间的可见性。
这条规则体现了happens-before原则具有传递性。
只有start( )之后线程才真正运行,否则Thread也只是一个对象。
这条规则是指,如果线程收到中断信号,那么在此之前势必调用了interrupt( )方法。
这条规则意思是,线程任务的执行、逻辑单元执行肯定要先发生于线程死亡之前。
标签:原子性操作 内存 没有 方法 java内存模型 三种方式 程序 运行 被锁
原文地址:https://www.cnblogs.com/privateNotesOfAidanChen/p/12897905.html