栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java40-JMM-happens-before-析构器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java40-JMM-happens-before-析构器

happens-before JMM相关

java内存模型是为了解决在并发环境下由于CPU缓存、编译器和处理器的指令重排序 导致的可见性、有序性问题。
JMM解决指令重排其实是定义了一项happens-before规则。
JMM设计意图:程序员而言,需要内存模型易于理解、编程,需要一个强内存模型来编码;编译器和处理器而言,希望约束少一点,这样不会限制他们的执行效率。
JMM设计策略 (重排序) :
①对于会改变程序执行结果的重排序,JMM要求编译器和处理器必须禁止这种重排序;而对于不会改变执行结果的重排序,JMM不做处理;
②JMM为了满足对编译器和处理器的约束尽量少的条件,遵循规则是:只要不改变程序的执行结果,编译器和处理器想怎么优化就怎么优化;
java内存模型底层是通过内存屏障(memory barrier)来禁止重排序的。

概述

happens-before规则:前一个操作的结果对后续操作是可见的。
JMM设计分为两部分:程序员 + 编译器处理器
JMM为程序员提供的视角是:按顺序执行,且满足一个操作happens-before于另一个操作,即第一个操作执行结果对第二个操作可见。(JMM向程序员做出的保证)
JMM为编译器和处理器提供的视角是:在不改变程序结果的前提下,编译器和处理器怎么优化都可以。
happens-before这样做的目的,都是为了在不改变程序执行结果的前提下,尽可能地提高程序执行的并行度。
happens-before本质:一种可见性,A happens-before B 意味着A事件对B事件来说是可见的,无论A事件和B事件是否发生在同一个线程里。假设事件A发生在线程1上,事件B发生在线程2上,happens-before规则保证线程2上能看到A事件的发生。

一个happens-before规则对应于一个或多个编译器和处理器重排序规则。

happens-before规则定义 1 程序顺序规则

一个线程中,按照程序顺序,前面的操作happens-before于后续的任意操作。
xhj理解:即前面操作的结果对后续操作是可见的

double pi = 3.14; //A
double r = 1.0; // B
double area = pi * r * r; // C

// 操作A happens-before 于操作B
2 监视器锁规则

对一个锁的解锁,happens-before于随后对这个锁的加锁。该锁说的就是synchronized。
xhj:解锁操作 执行可见于 之后(时间顺序)对同一把锁的加锁操作。

synchronized(this){ // 自动加锁
// x共享变量,初始值是10
	if(this.x < 12){
		this.x = 12;
	}
}
// 自动解锁

// 加锁和释放锁操作都是编译器帮我们实现的。
// 也就是说线程A对共享变量的修改,在线程A释放锁之后,线程B进入代码块的时候,能够看到共享变量修改后的值 x = 12
3 Volatile变量规则

对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
xhj:对volatile域的写,对于后续对这个volatile域的读 是 可见的。(感觉像是禁用缓存的意思)

4 传递性

如果A happens-before B,且 B happens-before C,那么A happens-before C。

5 start()规则

主线程A启动子线程B后,子线程B能够看到主线程在启动子线程B之前的操作。

线程的启动操作,可见于 该线程执行的第一个操作。

6 join()规则

如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作 happens-before于 线程A从ThreadB.join()操作成功返回。

线程的最后一个操作 被后续操作可见 即它的终止事件(其他线程通过Thread.join()判断该线程是否中止)。

7 程序中断规则

对线程interrupt()方法的调用 先行于 被中断线程的代码检测到中断时间的发生。
xhj:线程对其他线程的中断操作 先行于 被中断线程所收到的中断事件。

8 对象finalize规则

一个对象的初始化完成(构造函数执行结束) 先行于 发生它的finalize()方法的开始。

9 构造器、析构器

构造器的最后一个操作 先行于 析构器的第一个操作。

析构器 构造方法 和 析构方法 作用正好相反
构造方法类构造对象时调用的方式,通常用来实例化对象以及开辟存储空间。
析构方法用来做清理垃圾碎片的工作
例如:在建立对象的时候,用new开辟了一块内存空间,应在退出前在析构方法中将它释放。
finalize()方法

在java的Object类中,protected void finalize() 是一个受保护的方法;
由于其在Object类中,且所有类都继承自Object类,那么任何类都能够覆盖这个方法,该方法用于释放对象所占有的相关资源。
特点:

  • 垃圾回收器是否会执行该方法以及何时执行该方法,都是不确定的;
  • finalize()方法有可能使对象复活,使对象恢复到可触及状态;
  • 垃圾回收器在执行finalize()方法的时候,假设出现异常,垃圾回收器不会报告异常,程序继续正常执行。
内存屏障
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/863061.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号