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

网站维护服务费discuz 做门户网站

网站维护服务费,discuz 做门户网站,大连制作网站企业,网站怎么提高百度权重Java 内存模型翻译自 Java Memory Model#xff0c;简称 JMM。它所描述的是多线程并发、CPU 缓存等方面的内容。 在每一个线程中#xff0c;都会有一块内部的工作内存#xff0c;这块内存保存了主内存共享数据的拷贝副本。但在 Java 线程中并不存在所谓的工作内存#xff0…Java 内存模型翻译自 Java Memory Model简称 JMM。它所描述的是多线程并发、CPU 缓存等方面的内容。 在每一个线程中都会有一块内部的工作内存这块内存保存了主内存共享数据的拷贝副本。但在 Java 线程中并不存在所谓的工作内存working memory它只是对 CPU 寄存器和高速缓存的抽象描述。 CPU 普及 线程是 CPU 调度的最小单位线程中的字节码指令最终都在 CPU 中执行。CPU 在执行的时候免不了要和各种数据打交道而 Java 中所有数据都是放在主内存中的。随着 CPU 的发展CPU 的执行速度越来越快但内存的技术并没有太大变化所以在内存中读取和写入数据的过程和 CPU 执行速度比起来差距会越来越大。如上图箭头所示CPU 对主内存的访问需要等待较长的时间这样就体现不出 CPU 超强的运算能力了。 因此为了压榨处理器性能达到高并发的效果在 CPU 中添加了高速缓存 cache 来作为缓冲。在执行运算时CPU 会将运算所使用到的数据复制到高速缓存中让运算能够快速进行。当运算结束后再将缓存中的结果刷回主内存。这样 CPU 就不用等待主内存的读写操作了。如下图所示 上面的方案看起来一切正常。但问题也随之而来每个 CPU 处理器都有自己的高速缓存同时又共同操作同一块主内存当多个处理器同时操作主内存时可能导致数据不一致这就是缓存一致性问题。 缓存一致性问题 现在市面上的手机通常有2个或多个 CPU其中一些 CPU 还有多核。每个 CPU 在某一时刻都能运行一个线程。如果 Java 程序是多线程的就有可能存在多个线程在同一时刻被不同的 CPU 执行的情况 如下代码所示 public int x 0; public int y 0;Thread p1 new Thread(){public void run(){int r1 x;y 1;} };Thread p2 new Thread(){public void run(){int r2 y;x 2;} };p1.start(); p2.start(); 假设我们的一台设备上有2个CPU分别为 C1 和 C2将上面这段代码执行在这台设备上最后打印出的 r1 和 r2 值分别是多少答案是不确定的。 情况1r1 0, r2 1 假设 P1 现在 C1 中执行完毕并成功刷新回主内存中此时 r1 0, x 0, y 1。然后 P2 在 C2 中执行从主内存中加载 y 1 并赋值给 r2。此时 r2 1, x 2, y 1, r1 0。 情况2r1 2, r2 0 假设 P2 现在 C1 中执行完毕并成功刷新回主内存中此时 r2 0, x 2, y 0。然后 P1 在 C2 中执行从主内存中加载 x 2 并赋值给 r2。此时 r1 2, x 2, y 1, r2  0。 情况3r1 0, r2 0(特殊) x, y的值分别缓存在 C1 和 C2 的缓存中首先 P1 在 C1 中执行完毕但是并未将结果刷新回主内存中此时主内存中的 x 0, y 0。然后 P2 在 C2 中执行缓存中的 y 0 将其赋值给 r2此时r2 0 , x 2, y 1如下图所示 虽然 C1 和 C2 的主内存中修改了 x, y 的值但并未将它们刷新到主内存中。这就是缓存一致性问题。 指令重排 除了缓存一致性问题还存在另外一种硬件问题即指令重排。为了使 CPU 内部的运算单元能够尽量充分利用处理器可能会对输入的字节码指令进行重排序处理也就是处理器优化。比如 Java 虚拟机的即时编译器JIT)如以下代码 a 1; b 2; a a 1 编译后的字节码指令如下 可以看出在上述红框中的指令是表达的同一种语义并且指令7并不依赖指令2和3在这种情况下CPU 会对指令的顺序做如下优化。 从 Java 语言的角度看这种优化如下 也就是说在 CPU 层面Java 有时候并不会严格按照文件中的顺序去执行。 缓存一致性问题和指令重排的内容表明如果我们任由 CPU 优化那么我们编写的 java 代码所执行的效果会大大出乎我们的意料。 为了解决这个问题让 Java 代码在不同硬件、不同操作系统中输出的结果达到一致。Java 虚拟机规范提出了一套机制-- java 内存模型。 Java 内存模型 内存模型是一套共享内存系统中多线程读写操作行为的规范。这套规范屏蔽了底层各种硬件和操作系统的内存访问差异。解决了 CPU 多级缓存、CPU优化、指令重排等导致的内存访问问题从而保证 Java 程序尤其是多线程程序在各种平台下对内存的访问效果一致。 在 java 内存模型中统一用工作内存来当作 CPU 中寄存器或高速缓存的抽象。线程之间的共享变量存储在主内存中每个线程都有一个私有工作内存类比 CPU 中的寄存器或者高速缓存本地工作内存中存储了该线程读/写共享变量的副本。 在这套规范中有一个非常重要的规则 happens-before 先行发生原则。 happens-before 先行发生原则 happens-before 用于描述两个操作的内存可见性通过保证可见性的机制可以让应用程序免于数据竞争干扰。 定义如果一个操作 A happens-before 另一个操作 B那么操作 A 的执行结果将对操作 B 可见。 反过来理解如果操作 A 的结果必须对操作 B 可见那么操作 A 必须 happens-before 操作 B。 举例 private int value 0;public void setValue(int value){value 1; }public int getValue(){return value; } 假设 setValue 就是操作 AgetValue 就是操作 B如果先后在两个线程中调用 A 和 B那最后在 B 操作中返回的 value 值是多少呢 情况1A happens-before B 不成立 当线程调用操作 B 时即使操作 A 已经在其它线程中被调用过并且 value 也被成功设置为1。但这个修改对操作 B 仍然是不可见的根据上面 CPU 缓存的内容 value 值有可能返回1也有可能返回0。 情况2A happens-before B 成立 根据 happens-before 的定义先行发生动作的结果对后续动作是可见的也就是先执行 A  后的结果对后续的操作 B 是始终可见的。即先调用 setValue() 将 value 的值修改为1后续在其它线程中调用 getValue() 获得的 value 值一定是1。 在 Java 中的两个操作如何算符合 happens-before 规则了呢 JMM 中定义了以下几种情况是自动符合 happens-before 规则的。 1. 程序次序规则 在单线程内部如果一段代码的字节码顺序也隐私符合 happens-before 原则那么逻辑顺序靠前的字节码执行结果一定是对后续逻辑字节码可见。如下代码所示   int a 10; // 1 b b 1; //2 当代码执行到2处时a 10 这个结果已经是公之于众的至于用没用到 a  这个结果则不一定比如上面的代码中没有用到 a 10 这个结果。 2. 锁定规则 一个锁如果处于被锁定状态那么必须先执行 unlock 操作后才能进行 lock 操作。 3. 变量规则 volatile 保证了线程可见性。如果一个线程先写了一个 volatile 变量然后另一个线程去读这个变量那么这个写操作一定是 happens-before 读操作的。 4. 线程启动规则 Thread 对象的 start() 方法先行发生于此线程的每一个动作。假定线程 A 在执行过程中通过执行 ThreadB.start() 来启动线程 B那么线程 A 对共享变量的修改在线程 B 开始执行后确保对线程 B 可见。 4. 线程中断规则 对线程interrupt()方法的调用先行发生于被中断线程的代码检测直到中断事件的发生。 5. 线程终结规则 线程中所有的操作都发生在线程的终止检测之前可以通过Thread.join()方法结束、Thread.isAlive() 的返回值等方法检测线程是否终止执行。假定线程A在执行的过程中,通过调用ThreadB.join()等待线程B终止那么线程B在终止之前对共享变量的修改在线程A等待返回后可见。 6. 对象终结规则 一个对象的初始化完成发生在它的finalize()方法开始前。 happens-before 原则具有传递性 如果操作 A happens-before 操作 B而操作 B happens-before 操作 C那么操作 A 一定 happens-before 操作 C。 Java 内存模型应用 根据 happens-before 原则能够解决在并发环境下操作之间是否可能存在冲突的所有问题。可以可以通过 Java 提供的一系列关键字将实现的多线程操作“happens-before 化”。happens-before 化”是将本来不符合 happens-before 原则的某些操作通过某种手段使它们符合 happens-before 原则。 方法1使用 volatile 关键字 private volatile int value 0;public void setValue(int value){value 1; }public int getValue(){return value; } 方法2使用 synchronized 关键字修饰操作 private int value 0;public void setValue(int value){synchronized{value 1;} }public int getValue(){synchronized{return value;} } 通过以上两个方式都可以使 setVaule() 和 getValue() 符合 happens-before 原则。当在某一线程中调用 setVaule()后再在其它线程中调用 getValue() 获取到的值一定是 1。 总结 Java 内存模型的来源 主要是因为 CPU 缓存和指令重排等优化操作造成多线程程序结果不可控。 Java 内存模型是什么 本质上它就是一套规范在这套规范中有一条最重要的 happens-before 原则。 Java 内存模型的使用 简单介绍了两种方式volatile 和 synchronized。
http://www.ho-use.cn/article/10823981.html

相关文章:

  • 到哪里查网站备案信息做网站需学什么条件
  • 青岛私人做网站wordpress收款
  • 中国门户网站建设重要性做网站需要学哪些语言
  • 招聘网站可做哪些推广方案广州网站开发 细致广州亦客网络
  • 新手怎么样学做网站简单的app开发
  • 织梦门户网站源码下载小型网站建设公司
  • 宝山做网站价格百度免费校园网站建设
  • 兼职网站建设收费网app开发
  • 德洲网站建设如何在网上推广信用卡
  • 亚马逊amz123seo引擎优化
  • 领先的响应式网站建设平台全网推广的方式
  • 如何做聚合类网站wordpress支持python吗
  • 网站改了模板被百度降权最便宜做个网站多少钱
  • 给钱做任务的网站重庆seo推广外包
  • 设计主题网站怎样看一个网站的信息吗
  • 织梦网站管理系统小说推广合作平台入口
  • 网站设计步骤大全萧山区建设工程质量监督站网站
  • 中国建设教育协会培训中心网站站优化
  • 做网站生意多吗短网址助手
  • 什么网站收录快关键词优化seo费用
  • 平台网站怎么优化中搜seo
  • 商城网站功能介绍建设网站要求有哪些
  • 门户网站制作平台视觉做的比较好的国外网站
  • 学校建设网站费用申请报告关键词排名优化系统
  • 网站维护一次一般要多久seo的目的是什么
  • 网站开发中 html网站自己优化
  • 链接提交百度站长平台wordpress重新配置ftp
  • 免费的网站域名查询方法有哪些加拿大28平台微信
  • 只有后端可以做网站吗wordpress标签3d
  • 企业制作网站一般多少钱网站首页制作代码