资讯专栏INFORMATION COLUMN

Java 线程执行与变量可见性的 happen-before 关系

zsy888 / 478人阅读

摘要:线程执行与变量可见性的关系什么是的关系的关系是保证一个线程执行的操作结果对不同线程中的另一个操作可见。执行写入和读取到内存的两个线程可以在时钟时间方面与其他操作保持一致,但可能看不到彼此一致的更改内存一致性错误,除非它们有关系。

Java 线程执行与变量可见性的 happen-before 关系 什么是 happen-before 的关系

happen-before 的关系是保证一个线程执行的操作结果对不同线程中的另一个操作可见。

Happens-before 定义程序中所有操作的部分排序。为了保证执行操作Y的线程可以看到操作X的结果(X和Y是否出现在不同的线程中),X和Y之间必然存在一个先发生的关系。在没有happen-before 排序的情况下在两个操作之间,JVM可以根据需要自由重新排序(JIT编译器优化)。

happen-before 的不仅仅是"时间"中的动作重新排序,而且还保证了对内存的读写顺序。执行写入和读取到内存的两个线程可以在时钟时间方面与其他操作保持一致,但可能看不到彼此一致的更改(内存一致性错误),除非它们有happen-before 关系。

如何建立 happen-before 关系?

以下是发生之前的规则:

单线程规则:单个线程中的每个操作都发生在该程序顺序中稍后出现的该线程中的每个操作之前。

监视器锁定规则:监视器锁定(退出同步方法/块)上的解锁发生 - 在每次后续获取同一监视器锁定之前。

易失性变量规则:在对该相同字段的每次后续读取之前发生对易失性字段的写入。易失性字段的写入和读取具有与进入和退出监视器(读取和写入时的同步块)类似的内存一致性效果,但实际上没有获取监视器/锁定。

线程启动规则:线程上的 Thread.start() 调用发生在启动线程中的每个操作之前。假设线程A通过调用threadA.start() 生成一个新线程B. 在线程B的run方法中执行的所有操作都将看到线程A调用threadA.start() 方法,之前(仅在线程A中)发生在它们之前。

线程连接规则:线程中的所有操作都发生在任何其他线程从该线程上的连接成功返回之前。假设线程A通过调用threadA.start() 生成一个新线程B,然后调用threadA.join() 。线程A将在 join() 调用时等待,直到线程B的run方法完成。在join方法返回后,线程A中的所有后续操作都将看到线程B的run方法中执行的所有操作都发生在它们之前。

传递性:如果A发生在B之前,B发生在C之前,那么A发生在C之前。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75687.html

相关文章

  • java内存模型

    摘要:顺序一致性内存模型有两大特性一个线程中所有操作必须按照程序的顺序执行。这里的同步包括对常用同步原语的正确使用通过以下程序说明与顺序一致性两种内存模型的对比顺序一致性模型中所有操作完全按程序的顺序串行执行。 java内存模型 java内存模型基础 happen-before模型 JSR-133使用happen-before的概念来阐述操作之间的内存可见性。在JMM中,如果一个操作执行的结...

    2i18ns 评论0 收藏0
  • java volatile 关键字

    摘要:举个例子,在多线程不使用环境中,每个线程会从主存中复制变量到缓存以提高性能。保证了变量的可见性关键字解决了变量的可见性问题。在多线程同时共享变量的情形下,关键字已不足以保证程序的并发性。 volatile 关键字能把 Java 变量标记成被存储到主存中。这表示每一次读取 volatile 变量都会访问计算机主存,而不是 CPU 缓存。每一次对 volatile 变量的写操作不仅会写到 ...

    scola666 评论0 收藏0
  • Java并发编程-原子操作

    摘要:这个规则比较好理解,无论是在单线程环境还是多线程环境,一个锁处于被锁定状态,那么必须先执行操作后面才能进行操作。线程启动规则独享的方法先行于此线程的每一个动作。 1. 指令重排序 关于指令重排序的概念,比较复杂,不好理解。我们从一个例子分析: public class SimpleHappenBefore { /** 这是一个验证结果的变量 */ private st...

    SillyMonkey 评论0 收藏0
  • 高并发 - 基础

    摘要:异步非阻塞方式,任务的完成的通知由其他线程发出。并发并行死锁饥饿活锁死锁线程持有,线程持有。如等,在多线程情况下,该操作不是原子级别的而是原子的,所以一般用于状态标记。 同步/异步、阻塞/非阻塞 同步/异步是 API 被调用者的通知方式。阻塞/非阻塞则是 API 调用者的等待方式(线程挂机/不挂起)。 同步非阻塞 Future方式,任务的完成要主线程自己判断。如NIO,后台有多个任务在...

    phpmatt 评论0 收藏0
  • Java线程笔记(一):JMM基础关键字

    摘要:当线程执行完后进入状态,表示线程执行结束。其中和表示两个线程。但要注意,让出并不表示当前线程不执行了。关键字其作用是防止指令重排和使线程对一个对象的修改令其他线程可见。 JMM特性一览 Java Memory Model的关键技术点都是围绕着多线程的原子性、可见性和有序性来建立的。因此我们首先需要来了解这些概念。 原子性(Atomicity) 原子性是指一个操作是不可中断的。即使是在多...

    cyixlq 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<