线程是操作系统的最小调度单位,也是执行单位,为了追求高性能,线程里面的指令执行顺序是不定的,这来自编译器会重排序指令,处理器会乱序或者并行的执行,编译器还有可能将数据放在处理器的寄存器中等,这些优化技术在单线程的程序中表现得很好,但是到了多线程程序中就有问题了。
首先要了解下Java的内存结构,然后我们再进入线程和内存的关系, Java的内存结构如下
如果多线程之间不共享数据,这也表现得很好,但是如果多线程之间要共享数据,那么这些乱序执行,数据在寄存器中这些行为将导致程序行为的不确定性,现在处理器已经是多核时代了,这些问题将会更加严重,每个线程都有自己的工作内存,多个线程共享主内存,如图
如果共享数据,什么时候同步到主内存让别人的线程读取数据呢?这又是不确定的,如果非要一致,那么代价高昂,这将牺牲处理器的性能,所以现在的处理器会牺牲存储一致性来换取性能,如果程序要确保共享数据的时候获得一致性,处理器通常了提供了一些关卡指令,这个可以帮助程序员来实现,但是各种处理器都不一样,如果要使程序能够跨平台是不可能的,怎么办?
使用Java,由JMM来屏蔽,我们只要和JMM的规定来使用一致性保证就搞定了,那么JMM又提供了什么保证呢?JMM的定义是通过动作的形式来描述的,所谓动作,包括变量的读和写,监视器加锁和释放锁,线程的启动和拼接,这就是传说中的happen before,要想A动作看到B动作的结果,B和A必须满足happen before关系,happen before法则如下:
1, 程序次序法则,如果A一定在B之前发生,则happen before,
2, 监视器法则,对一个监视器的解锁一定发生在后续对同一监视器加锁之前
3, Volatie变量法则:写volatile变量一定发生在后续对它的读之前
4, 线程启动法则:Thread.start一定发生在线程中的动作
5, 线程终结法则:线程中的任何动作一定发生在括号中的动作之前(其他线程检测到这个线程已经终止,从Thread.join调用成功返回,Thread.isAlive()返回false)
6, 中断法则:一个线程调用另一个线程的interrupt一定发生在另一线程发现中断。
7, 终结法则:一个对象的构造函数结束一定发生在对象的finalizer之前
8, 传递性:A发生在B之前,B发生在C之前,A一定发生在C之前。
- 大小: 28.3 KB
- 大小: 10.9 KB
分享到:
相关推荐
在 JMM 中,`happen-before` 规则是定义这些同步特性的重要概念。它是一种偏序关系,确保了在程序中两个操作之间的执行顺序,并且保证了前一个操作的结果对后一个操作可见。以下是一些 `happen-before` 的典型规则:...
为了解决这类问题,引入了happens-before原则,这是Java内存模型(JMM)的一部分,它规定了一种特定的内存操作顺序,以确保正确同步。具体来说: 1. **线程操作的顺序**:在一个线程内,所有的操作都按照程序的顺序...
在 Java 内存模型(JMM)中,happens-before 原则是一个核心概念,它规定了多线程环境下的可见性原则。该原则的核心思想是:两个操作之间的 happens-before 关系,并不意味着前一个操作必须在后一个操作之前执行。...
JMM提供了一些规则来保证有序性,例如Happen-Before规则。 ##### 指令重排 指令重排是为了提高程序执行效率而进行的一种优化手段,但它可能会导致线程间的执行顺序混乱。例如,在单线程环境下,`A = B + C`这样的...
Happen-Before原则是JMM中的一个关键概念,它定义了在多线程环境下,一个操作对另一个操作的可见性。如果A操作Happen-Before B操作,那么B能看到A的结果。例如,线程的启动操作Happen-Before该线程的任何读写操作,`...
JMM规定了happen-before规则,这个规则限制了那些语句执行在前,那些语句执行在后。 知识点6:volatile关键字 volatile关键字可以保证变量的可见性和有序性,但是不能保证原子性。volatile关键字可以用在轻量级的...
volatile关键字也可以确保变量的顺序性,即volatile变量的写操作总是 happen-before 于读操作。 Java内存模型(JMM) Java虚拟机有自己的内存模型(Java Memory Model,JMM),JMM可以屏蔽掉各种硬件和操作系统的...
16. **Happen-Before原则**:这是JMM(Java内存模型)的一部分,定义了线程间的可见性和有序性。遵循这些原则可以确保并发程序的正确性。 17. **volatile防止指令重排**:volatile关键字可以阻止其修饰的变量在不同...
happen-before原则保证了在并发环境下,一个操作的结果对另一个操作是可见的,从而保证程序执行顺序的正确性。 指令重排序是指编译器或处理器为了优化性能而对指令进行重新排序。在并发编程中,指令重排序可能会...