当前位置: 首页 > news >正文

黄山区建设学会网站惠州网站制作推广公司排名

黄山区建设学会网站,惠州网站制作推广公司排名,保定网络营销,定制网站与模板网站的主要区别内存模型的基础 通信  线程之间以何种机制来交换信息 共享内存  隐式通信消息传递  显示通信 同步  程序中用于控制不同线程间操作,发生的相对顺序的机制 共享内存  显式同步消息传递  隐式同步 Java线程线程之间是通过共享内存的方式实现通信的. 内存模型的抽… 内存模型的基础 通信  线程之间以何种机制来交换信息 共享内存  隐式通信消息传递  显示通信 同步  程序中用于控制不同线程间操作,发生的相对顺序的机制 共享内存  显式同步消息传递  隐式同步 Java线程线程之间是通过共享内存的方式实现通信的. 内存模型的抽象结构 共享变量 共享变量手内存模型影响,线程会去主内存里去加载共享变量,当线程需要改变共享变量时,会将本地内存已更改的副本提交到主内存. 局部变量 局部变量不会受内存模型的影响 线程之间通信 指令重排 编译器优化的重排序指令级并行的重排序内存系统的重排序 什么是指令重排? int i0; 2 int j1; 按照我们的认知,程序是一行一行往下执行的,但是由于编译器或运行时环境为了优化程序性能,采取对指令进行重新排序执行,也就是说在计算机执行上面两句话的时候,有可能第二条语句会优先于第一条语句执行. 然而并不是所有的指令都能重排,重排需要基于数据依赖性. 数据依赖性 如果两个操作访问同一个变量且这两个操作中有一个为写操作此时这两个操作之间就存在数据依赖性。数据依赖分下列三种类型 名称代码示例说明写后读a1;ba;写一个变量之后,再读这个位置.写后写a1;a2;写一个变量之后,再写这个变量.读后写ab;b1;读一个变量之后,再写这个变量. 上面的情况,如果重排序了两个操作的执行顺序,程序的执行结果将会跟预期完全不一样. 所以说,虽然编译器和处理器可能会对操作做重排序,但是编译器和处理器在重排序时,会遵守数据依赖性编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。 注意这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。 as-if-serial 定义:不管怎么重排序(编译器和处理器为了提⾼并⾏度)(单线程) 程序的执⾏结果不能被改变。编译器、runtime和处理器都必须遵守as-if-serial语义。 happens-before happens-before是JMM的最核心概念之一 JMM设计意图 程序员对内存模型的使用 为程序员提供足够强的内存可见性保证 编译器和处理器对内存模型的实现 对编译器和处理器的限制要尽可能的放松 JMM禁止: 禁止编译器和处理器会改变程序执行结果的重排序. JMM允许: 允许编译器和处理器不会改变程序执行结果的重排序. happens-before规则 在JMM中如果⼀个操作执⾏的结果需要对另⼀个操作可⻅那么这两个操作之间必须要存在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于被中断线程的代码检测到中断事件的发⽣.对象终结规则  ⼀个对象的初始化的完成也就是构造函数执⾏的结束⼀定 happens-before它的finalize()⽅法. JMM向程序员提供的happens-before规则能满⾜程序员的需求. JMM对编译器和处理器的束缚已经尽可能少. JMM对程序员的承诺 如果⼀个操作happens-before另⼀个操作那么第⼀个操作的执⾏结果将对第⼆个操作 可⻅⽽且第⼀个操作的执⾏顺序排在第⼆个操作之前. JMM对编译器和处理器重排序的约束原则 两个操作之间存在happens-before关系并不意味着Java平台的具体实现必须要按照 happens-before关系指定的顺序来执⾏. 例子: 1 public class Demo29 { 2 int a0; 3 boolean flagfalse; 4 public void writer(){ 5 a1; //1 6 flagtrue; //2 7 } 8 public void reader(){ 9 if(flag){ //3 10 int ia * a; //4 11 } 12 } 13 }假如线程B在进行操作4时,能否看到线程A在操作1对共享变量a的写入呢? 不一定 | 时刻 | 线程A | 线程B | | T1 | flagtrue | | | T2 | | if(flag) | | T3 | | int ia*a | | T4 | a1 | |当线程A在执行writer方法时,因为指令重排序,会先执行flagtrue,再执行a1.而线程B在执行操作4时就会读不到线程A对共享变量a的写入,导致运行结果超出预期. 解决方案1: 通过加锁的方式来解决 1 public class Demo29 { 2 int a0; 3 boolean flagfalse; 4 public synchronized void writer(){ 5 a1; //1 6 flagtrue; //2 7 } 8 public synchronized void reader(){ 9 if(flag){ //3 10 int ia * a; //4 11 } 12 } 13 }锁的内存语义: 线程A释放⼀个锁实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A 对共享变量所做修改的)消息。线程B获取⼀个锁实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共 享变量所做修改的)消息。线程A释放锁随后线程B获取这个锁这个过程实质上是线程A通过主内存向线程B发 送消息。 volatile的作用 volatile原理被volatile关键字修饰的变量编译器与运行时都会注意到这个变量是共享的因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方因此在读取volatile类型的变量时总会返回最新写入的值。在访问volatile变量时不会执行加锁操作因此也就不会使执行线程阻塞因此volatile变量是一种比sychronized关键字更轻量级的同步机制。当对非 volatile 变量进行读写的时候每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU每个线程可能在不同的CPU上被处理这意味着每个线程可以拷贝到不同的 CPU cache 中。而声明变量是 volatile 的JVM 保证了每次读变量都从内存中读跳过 CPU cache 这一步。volatile在Java并发编程中常用于保持内存可见性和防止指令重排序。内存可见性Memory Visibility所有线程都能看到共享内存的最新状态防止指令重排在基于偏序关系的Happens-Before内存模型中指令重排技术大大提高了程序执行效率但同时也引入了一些问题。可见性volatile保持内存可见性的特殊规则read、load、use动作必须连续出现assign、store、write动作必须连续出现每次读取前必须先从主内存刷新最新的值每次写入后必须立即同步回主内存当中。也就是说volatile关键字修饰的变量看到的随时是自己的最新值。在线程1中对变量v的最新修改对线程2是可见的。内存屏障volatile防止指令重排的策略在每个volatile写操作的前面插入一个StoreStore屏障在每个volatile写操作的后面插入一个StoreLoad屏障在每个volatile读操作的后面插入一个LoadLoad屏障在每个volatile读操作的后面插入一个LoadStore屏障。volatile 性能volatile 的读性能消耗与普通变量几乎相同但是写操作稍慢因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。 volatile内存语义 线程A写⼀个volatile变量实质上是线程A向接下来将要读这个volatile变量的某个线程 发出了(其对共享变量所做修改的)消息。线程B读⼀个volatile变量实质上是线程B接收了之前某个线程发出的(在写这个volatile 变量之前对共享变量所做修改的)消息。线程A写⼀个volatile变量随后线程B读这个volatile变量这个过程实质上是线程A通过 主内存向线程B发送消息。 volatile内存语义的实现 是否能重排序第二个操作第一个操作普通读/写普通读/写Yvolatile读Nvolatile写Y当第⼆个操作是volatile写时不管第⼀个操作是什么都不能重排序。 当第⼀个操作是volatile读时不管第⼆个操作是什么都不能重排序。 当第⼀个操作是volatile写第⼆个操作是volatile读时不能重排序。 内存屏障 屏障类型指令示例说明LoadLoad BarriersLoad1;LoadLoad;Load2确保Load1数据的装载先于Load2及所有后续装载指令的装载StoreStore BarriersStore1;StoreStore;Store2确保Store1数据对其他处理器可见(刷新达到内存)先于Store2及所有后续存储指令的存储LoadStore BarriersLoad1;LoadStrore;Store2确保Load1数据装载先于Store2及所有后续的存储指令刷新到内存StoreLoad BarriersStore;StoreLoad;Load2确保Store1数据对其他处理器变得可见(指刷新到内存)先于Load2及所有后续装载指令的装载.StoreLoad Barriers会使该屏障之前的所有内存访问指令(存储和装载指令)完成之后,才执行该屏障之后的内存访问指令 在每个volatile写操作的前⾯插⼊⼀个StoreStore屏障在每个volatile写操作的后⾯插⼊⼀个StoreLoad屏障在每个volatile读操作的后⾯插⼊⼀个LoadLoad屏障在每个volatile读操作的后⾯插⼊⼀个LoadStore屏障 Final的内存语义 写final域的重排序规则 JMM禁止编译器把final域的写重排序到构造函数之外.编译器会在final域的写之后,构造函数return之前插入一个StoreStore屏障 读final域的重排序规则 在⼀个线程中初次读对象引⽤与初次读该对象包含的final域JMM禁⽌处理器重排序这两个操作在构造函数内对一个final引用的对象的成员域的写入,与随后在构造函数外把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序 写final域的重排序规则 在构造函数内对⼀个final引⽤的对象的成员域 的写⼊与随后在构造函数外把这个被构造对象的引⽤赋值给⼀个引⽤变量这两个操作之 间不能重排序。 多线程下的单例模式 双重检查锁定 1 public class DoubleCheckedLocking {2 private static DoubleCheckedLocking doubleCheckedLocking;3 4 private DoubleCheckedLocking() {5 6 }7 8 public static DoubleCheckedLocking getInstance() { 9 if (doubleCheckedLocking null) { 10 synchronized (DoubleCheckedLocking.class) { 11 if (doubleCheckedLocking null) { 12 doubleCheckedLocking new DoubleCheckedLocking();//问题出现在这里 13 } 14 } 15 } 16 return doubleCheckedLocking; 17 } 18 }我们来看看这段双重检查锁定的单例模式有什么问题? 线程A设置指向刚分配的内存地址后,线程B就判断doubleCheckedLocking对象是否为空,然后直接返回未初始化的doubleCheckedLocking对象,这样会引发出很严重的问题. 解决方案1: 使用volatile,禁止2和3重排序 1 public class DoubleCheckedLocking { 2 private volatile static DoubleCheckedLocking doubleCheckedLocking; 3 4 private DoubleCheckedLocking() { 5 6 } 7 8 public static DoubleCheckedLocking getInstance() { 9 if (doubleCheckedLocking null) { 10 synchronized (DoubleCheckedLocking.class) { 11 if (doubleCheckedLocking null) { 12 doubleCheckedLocking new DoubleCheckedLocking();//问题出现在这里 13 } 14 } 15 } 16 return doubleCheckedLocking; 17 } 18 }解决方案2: 基于类初始化,允许2和3重排序,但不允许其他线程看到这个重排序 1 public class InstanceFactory { 2 private static class InstanceHolder { 3 public static DoubleCheckedLocking doubleCheckedLocking new DoubleCheckedLocking(); 4 } 5 6 public static DoubleCheckedLocking getInstance() { 7 return InstanceHolder.doubleCheckedLocking; 8 } 9 }这里使用到了静态内部类的静态属性,类的静态属性只会在第一次调用的时候初始化,而且会有一个Class对象的初始化锁,从而确保只会发生一次初始化. 最后祝大家早日学有所成拿到满意offer
http://www.pierceye.com/news/241930/

相关文章:

  • 有做浏览单的网站jsp网站开发过程
  • 做网站用小型机或服务器wordpress 喜欢
  • 网站建设与维护采访稿中国建设银行电脑版
  • 企业网站建设变相收取等级保护费手游平台十大排名
  • 影响力网站建设恩施网站开发
  • 美术馆网站建设总体要求承德信息发布微信平台
  • 同城便民网站开发为什么企业需要建设网站
  • 网站制作推荐新鸿儒黄山游玩攻略及费用
  • 二手车网站的建设app与微网站的区别是什么
  • 深圳做棋牌网站建设哪家便宜网站域名更改后怎么做映射
  • 长沙网站seo公司知名网站设计服务商
  • 网站建设会议讲话lol视频网站源码
  • 深圳市哪些公司做网站好wordpress小插件下载地址
  • 佛山优化网站公司网站策划书格式及范文
  • 上海网站建设公司秦皇岛网站seo
  • 外贸网站推广 sit淮安市广德育建设网站
  • 准备建网站该怎么做淘宝店铺
  • 1688外贸网站国外购物网站哪个最好
  • 怎么修改网站关键词网站建设的地方
  • 江苏运营网站建设业务淘宝推广引流方法有哪些
  • 快手评论点赞网站建设专业分站微信小程序开发者中心
  • mvc5网站开发之六 管理员p2网站模板
  • 黄页网站推广公司网站建设公司包括哪些内容
  • 网站平台建设目标修改网站j广州网络公司
  • 网站制作商城正规免费发布信息网站
  • 建设企业网站的人员组成莱芜网站建设费用
  • 长春建站网站西宁做网站君博专注
  • 学校实验室网站建设现状怎么做网站 ppt
  • 网站建设骗子公司新开传奇网站发布网
  • 智能模板网站建设方案深圳团购网站设计