加入收藏 | 设为首页 | 会员中心 | 我要投稿 惠州站长网 (https://www.0752zz.com.cn/)- 办公协同、云通信、物联设备、操作系统、高性能计算!
当前位置: 首页 > 业界 > 正文

电子邮件安全的五大趋势

发布时间:2021-02-01 10:17:14 所属栏目:业界 来源:互联网
导读:在JMM中,有两条规定: 线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写。 不同线程之间无法访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。 共享变量要实现可见性,必须经过如下两个步骤: 把本地

在JMM中,有两条规定:

线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写。

不同线程之间无法访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。

共享变量要实现可见性,必须经过如下两个步骤:

把本地内存1中更新过的共享变量刷新到主内存中。

把主内存中最新的共享变量的值更新到本地内存2中。

同时人们提出了内存屏障、happen-before、af-if-serial这三种概念来保证系统的可见性、原子性、有序性。

4.2 内存屏障

内存屏障 (Memory Barrier) 是一种CPU指令,用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。Java编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序,从而让程序按我们预想的流程去执行。具有如下功能:

保证特定操作的执行顺序。

影响某些数据(或则是某条指令的执行结果)的内存可见性。

在 volatile 中就用到了内存屏障,volatile部分已详细讲述。

4.3 happen-before

因为有指令重排的存在会导致难以理解CPU内部运行规则,JDK用 happens-before 的概念来阐述操作之间的内存可见性。在JMM 中如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系 。其中CPU的happens-before无需任何同步手段就可以保证的。

  • 程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
  • 监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
  • volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
  • 传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
  • start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。
  • join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。
  • 线程中断规则:对线程interrupt方法的调用happens-before于被中断线程的代码检测到中断事件的发生。

4.4 af-if-serial

af-if-serial 的含义是不管怎么重排序(编译器和处理器为了提高并行度),单线程环境下程序的执行结果不能被改变且必须正确。该语义使单线程环境下程序员无需担心重排序会干扰他们,也无需担心内存可见性问题。

5、volatile

volatile 关键字的引入可以保证变量的可见性,但是无法保证变量的原子性,比如 a++这样的是无法保证的。这里其实涉及到JMM 的知识点,Java多线程交互是通过共享内存的方式实现的。当我们读写volatile变量时具有如下规则:

当写一个volatile变量时,JMM会把该线程对应的本地中的共享变量值刷新到主内存。

当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

(编辑:惠州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读