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

一个主机多个网站网站做360推广需要什么条件

一个主机多个网站,网站做360推广需要什么条件,网站建设费需要摊销吗,网页游戏手机怎么玩今天来介绍下Java中的volatile关键字,volatile也是Java并发编程中不得不看的一个部分,在之前的文章中说到的双重检测单例模式其实也跟volatile也有不解之缘,另外volatile跟计算机体系架构(CPU)也是有着千丝万缕的关系。…

今天来介绍下Java中的volatile关键字,volatile也是Java并发编程中不得不看的一个部分,在之前的文章中说到的双重检测单例模式其实也跟volatile也有不解之缘,另外volatile跟计算机体系架构(CPU)也是有着千丝万缕的关系。

所以引入volatile之前,还是先来理解下背景:

由于计算的cpu、内存、IO设备的速度不均衡,cpu的速度最快,内存其次,IO设备速度最慢。因此在数据传输的过程中,就会出现cpu等待内存数据,内存等待IO数据的情况,整体上就会导致CPU不能高效利用,浪费资源。

于是科学家们为了提高CPU的利用率,不让CPU闲置,从操作系统层面和软件层面进行优化,比如之前同步?阻塞?到底什么是I/O模型这篇文章中提到的各种I/O模型,其目的就是为了越来越高效地利用CPU;此外,在CPU中,除了存在寄存器之外,还设置了一级、二级、三级...缓存,其目的也是为了缓解CPU和内存速度的差异,CPU可以优先从缓存中进行获取数据,这样不必每次都要去访问内存,也是一种优化方式。

但是事情往往总是两面性的,在优化性能和速度的同时,又引入了新问题,在一台主机具备多CPU多核的时代,计算机上的程序往往都是多用户多进程多线程式地去跑,在一台具有多CPU多核的机器上,程序是可以达到真正地并行计算的,而问题也就随之而来.......

下面是一段经典的多线程使用共享变量的例子:

int a = 0;
// 线程A运行a += 1
// 线程B运行a += 1

这里的共享变量a被线程A和线程B共享,可以试想下,最后a的结果是多少呢?

如果是单线程运行,毫无疑问,a的结果肯定是2,而在多线程的情况下,结果是多样的,有可能会出现a=1的情况,因为线程A和线程B是运行在一台2个CPU的机器上,线程A和线程B各占一个CPU,那也就是说线程A和线程B会各自享有自己占据的那个CPU上的寄存器和缓存,CPU在计算的时候会把要计算的数值取到寄存器中,计算完,会刷新到缓存或者主存(主存即内存)中,而当两个CPU各自把a这个变量加载进寄存器中后,会进行各自的计算,只要没有把CPU中寄存器中的值同步进内存中,那么两个线程中缓存中的a的值对双方来说都是不可见的,因此就如下图所示情况:

当线程A做完第1步操作:a=a+1. 这时候a的值还没有写到内存,而线程B也开始了a=a+1的操作,然后线程A将a的值写入内存,最后线程B也将a的值写入内存,所以a的值最终还是为1。

所以看到这里,可以看出来多线程情况下出现的问题,其实也是因为一系列的优化问题引起的,而在Java中要解决这个问题,Java也提供了相应的措施给开发者,比如今天要提到的volatile,还有诸如原子操作,锁操作等等。关于上面的那个例子,不得不再多一句最,即使用volatile来修饰变量a,其实也不能完全保证a可以得到正确的值,因为volatile仅仅保证的是内存可见性,而不是原子性,关于volatile保证内存可见性的问题下面会进行介绍。

今天主要介绍volatile这个关键字,通过对它做了一些解读和研究,主要分为这几点:

  1. 指令集重排序优化

  2. volatile保证内存可见性

  3. JMM(Java Memory Model模型),happens-before 规则

这几个点其实也是比较绕口的专业术语,也涉及到了JMM(Java Memory Model)的知识点,下面还是看例子,比较有清晰的认识:

以单例模式这个例子说起,单例模式中有一种写法是懒汉模式,并且为了多线程安全以及性能优化的考虑,用了双重检测的机制,在之前的文章单例模式(三)和单例模式(四)也讲过,看下面这段代码:

public class Singleton {    private static Singleton singleton;    private Singleton(){    }    public static Singleton getInstance(){        if (singleton == null){            synchronized (Singleton.class){                if(singleton == null)                    singleton = new Singleton();            }        }        return singleton;    }}

针对这种双重检测,更加严谨的做法就是在静态成员变量singleton 的前面加上volatile这个关键字,因为如果不加这个volatile可能会到导致多线程访问单例对象singleton的时候会发生报错,因为从高级语言层面来理解代码的执行是很难去想通这个逻辑的,因为Java会被编译为Class文件,就是字节码文件,字节码文件中包含的是一条条的指令,指令是由java虚拟机去解释执行的,所以这里的singleton = new Singleton();这句初始化语句其实被分解为下面几条语句:

new           #3                  // class cs/designpattern/singleton/bean/Singleton2...invokespecial #4                  // Method "<init>":()Vputstatic     #2                  // Field singleton:Lcs/designpattern/singleton/bean/Singleton2;

可以看到主要的指令执行就是:

  1. new对象

  2. 调用构造函数

  3. 引用赋值

而这三句指令目前的执行顺序是没有问题的,但是问题在于指令执行过程中,根据不同的计算机体系架构,CPU会对其进行指令集优化,当CPU优化指令集的时候,会对上面的指令集进行一种重排序的操作,而这种重排序的操作就会导致上面的指令顺序可能会变为:

  1. new对象

  2. 引用赋值

  3. 调用构造函数

这时候,会发生原本在第3步的引用赋值先于第2步的构造函数的调用,这时候就有可能发生这样的错误:假设这时候A、B两个线程来共同执行这端逻辑,A已经获取了锁,进入了锁里面的代码段,并且执行了1、2这两句指令操作,然后当B线程过来的时候,发现instance不为空了,所以就直接返回,而这时候A其实还没有执行第3个指令,所以B获取的instance其实就是一个未进行初始化(没有调用构造函数)的对象,这时候,如果使用这个对象就会报错。而引入volatile就是为了解决这个问题,代码如下:

public class Singleton {    private static volatile Singleton singleton;    private Singleton(){    }    public Singleton getInstance(){        if (singleton == null){            synchronized (Singleton.class){                if(singleton == null)                    singleton = new Singleton();            }        }        return singleton;    }}

volatile在这里的语义就是防止指令重排序,这样在初始化对象的时候,就能强制保证如下的顺序,保证了引用赋值不会先于构造函数的调用:

  1. new对象

  2. 调用构造函数

  3. 引用赋值

所以B线程就不会再获取一个未初始化过的对象了。

关于volatile防止指令重排序,其实也是JMM规定的happens-before规则之一, 在happens-before的规范中,volatile的一种语义就是防止指令重排序。

看完指令重排序后,来看volatile的另外一种语义:内存可见性

仍然来看一个小例子:

volatile boolean stop = false;// 线程A执行void shutdown(){    stop = true}
// 其他线程执行while(stop){  stopCurrentThread();

这里我们可以看到将stop这个多线程共享变量设置了volatile属性,为的就是可以立即让stop这个变量的值刷新到内存中,从而让其他线程执行的时候可以立即感知到stop这个变量的值发生了变,所以这里volatile的可见性语义其实就是体现在可以及时地将CPU寄存器或者CPU缓存中的计算结果及时地刷新到内存,起到多线程可以感知的效果,这也是JVM内存模型中happens-before定义的一个规则。

总结一下,今天主要记录了Java中volatile的两种语义:

  1. 防止指令重排序

  2. 内存可见性

关于JMM中的happens-before的规则,只是略微提了下,后面有时间也会做相应地记录和分析。


文章转载自:

http://tN0K7Sl7.jynzb.cn
http://psxi0QI6.jynzb.cn
http://7RIlNtkQ.jynzb.cn
http://JtdoeO4c.jynzb.cn
http://z6W17mE5.jynzb.cn
http://y8Sk3SXt.jynzb.cn
http://GoUHpnvg.jynzb.cn
http://AQ1m0Evh.jynzb.cn
http://2J8SnuuK.jynzb.cn
http://KZTvECRC.jynzb.cn
http://oUFx0MdP.jynzb.cn
http://26GqbHIz.jynzb.cn
http://WBqaU7r8.jynzb.cn
http://BYJMXsch.jynzb.cn
http://nrsHtVy4.jynzb.cn
http://C5yxj0Vn.jynzb.cn
http://9cu5ewuq.jynzb.cn
http://CP21yPNx.jynzb.cn
http://6cYZASLP.jynzb.cn
http://dwDw4Tdu.jynzb.cn
http://WeRfqQbt.jynzb.cn
http://ZEGTpFhn.jynzb.cn
http://iV8YzJxN.jynzb.cn
http://BUAIDQMQ.jynzb.cn
http://kpHr4gZP.jynzb.cn
http://6yCXv37S.jynzb.cn
http://Sar6p9be.jynzb.cn
http://nTFSVngr.jynzb.cn
http://wBD5hDh7.jynzb.cn
http://xsgUqymp.jynzb.cn
http://www.dtcms.com/wzjs/665399.html

相关文章:

  • 佛山新网站制作市场wordpress绑定百家号
  • 购物网站开发英文文献洛可可设计公司老板
  • 具有品牌的做网站西安网络科技有限公司
  • 上海大学生兼职做网站上海开发小程序和app的公司
  • 珠海网站建设 金蝶搜狐最大的门户网站
  • 南乐网站建设电话网站做成小程序
  • 手机网站开发调用照片温州快建网站
  • 企业网站类型主要包括广州黄埔区建设局网站局
  • 高新网站建设多少钱wordpress 变量
  • 环保网站源码公司logo图案大全
  • 可遇公寓网站哪个公司做的做徽标的网站
  • 网站建设用什么语言开发分销系统怎么做
  • 庆阳工程建设网站做的好的电商网站项目
  • 广州建设网站公司简介做美食网站有哪些
  • 建筑人才网官方网站中国建筑科学院有限公司认证中心宿迁网站网站建设
  • 徽文化网站建设方案书详细描述建设网站
  • 推荐家居网站建设app开发公司长沙
  • 阿里云服务器可以做商业网站郑州平面设计公司
  • 东莞型网站建设网站建设与运营推广的回报材料
  • 上海外贸营销网站建设建筑工程发布网站
  • 集团 投入巨资 做网站西安网络优化培训机构公司
  • 网站建设税收编码建设网站困难的解决办法
  • 宝塔做的网站怎么就可以进去了番禺 大石网站建设
  • 如何规划企业网站wordpress 外观 编辑
  • 如何做好电商网站平面设计谷歌应用商店app下载
  • 阅读的网站建设需要多少钱大连百度搜索排名
  • 建网站需花哪几种钱国家注册商标官方网
  • 深圳市公司网站建设平台买个网页多少钱
  • 锦州网站建设锦州设计师在线接单
  • 苏州网站建设提供商快餐小吃加盟方案