java 的内存一致性

此文是目前本人对 java 的内存一致性 的认识与理解,随着本人技术的成长,我将不断完善对它的理解与使用。针对网上各种各样的,杂乱随意的描述,我将尽最大努力,对其进行相应的描述。阐述过程中尽最大努力做到,描述准确,语义明确,简洁易读,容易理解。欢迎各位同道中人批评、讨论,加关注。

Java 语言规范里的 Happens-before 顺序,定义了,诸如对共享变量的读取和写入等内存操作的 happens-before 关系。只有当写操作发生在读操作之前,一个线程写的结果才能保证对另一个线程的读是可见的。Java 里的 synchronized 和 volatile 构造,以及 Thread.start() 和 Thread.join() 方法可以形成 happens-before 关系。尤其是:

  • 线程中的每个操作,都发生在同线程中其他的所有操作之前。这里的,其他的所有操作都是按程序顺序出现在前面所说的每个操作之后的。这里所描述的是同一线程中的 happens-before 关系。
  • 监视器的解锁(synchronized 块或 synchronized 方法的执行出口)发生在同一监视器的每个后续加锁(synchronized 块或 synchronized 方法的执行入口)之前。并且由于 happens-before 关系是可传递的,因此线程在解锁之前的所有程序执行操作都发生在任何线程加锁该监视器之后的所有程序执行动作之前。这里所描述的是针对同一监视器的解锁加锁间的 happens-before 关系。
  • 对 volatile 字段的写入发生在对同一字段的每次后续读取之前。对 volatile 字段的写入和读取具有与监视器的解锁加锁类似的内存一致性效果,但不需要互斥锁来达成这种内存一致性效果。这里所描述的是 volatile 所达成 happens-before 关系。
  • 在线程上调用启动方法 Thread.start() 的执行,发生在此已启动线程中的任何操作之前。这里所描述的是线程 Thread.start() 所产生的 happens-before 关系。
  • 线程 t 中的所有程序执行操作都发生在任何其他线程从调用 t.join() 成功返回之前。任何其他调用 t.join() 的线程会挂起,直到线程 t 中的所有程序执行操作结束,也就是从调用 t.join() 成功返回。这里有点拗口,如果你不能很好的理解,可以去学习一下 Thread.join() 。

另外,java.util.concurrent 及其子包中所有类的方法将这些规范扩展到更高级别的同步。尤其是:

  • 在将对象放入任何并发集合之前线程中的执行操作发生在另一个线程中从集合中访问或删除该对象元素的执行操作之前。
  • 在将 Runnable 提交给 Executor 之前,线程中的操作发生在其执行开始之前。类似地,在将 Callables 提交给 ExecutorService 之前,线程中的操作发生在其执行开始之前。
  • 由 Future 表示的异步计算所采取的执行操作,发生在另一个线程中通过 Future.get() 检索结果的后续执行操作之前。
  • “解除”同步器方法(例如 Lock.unlock、Semaphore.release 和 CountDownLatch.countDown )之前的执行操作,发生在对另一个线程中的同一同步器对象执行的成功“获取”方法(例如 Lock.lock、Semaphore.acquire、Condition.await 和 CountDownLatch.await)之后的执行操作之前。
  • 对于通过 Exchanger 成功交换对象的每对线程,每个线程中 exchange() 之前的执行操作发生在另一个线程中相应的 exchange() 之后的执行操作之前
  • 调用 CyclicBarrier.await 和 Phaser.awaitAdvance(及其变体)之前的执行操作发生在 the barrier action 执行的操作之前,以及 the barrier action 执行的操作发生在从其他线程中的相应的 await 成功返回之后的执行操作之前

小结,

本篇关于 java 内存一致性的描述,主要是通过其相应属性展开的。此文需要大家逐字逐句的认真阅读,仔细理解。可以通过动手写一下提及的关系,加深理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值