php做网站怎么布局wordpress node.js
news/
2025/9/22 17:19:13/
文章来源:
php做网站怎么布局,wordpress node.js,加强门户网站建设的通知,相亲网站如何做概述本文大部分整理自《Java并发编程的艺术》#xff0c;温故而知新#xff0c;加深对基础的理解程度。指令序列的重排序我们在编写代码的时候#xff0c;通常自上而下编写#xff0c;那么希望执行的顺序#xff0c;理论上也是逐步串行执行#xff0c;但是为了提高性能温故而知新加深对基础的理解程度。指令序列的重排序我们在编写代码的时候通常自上而下编写那么希望执行的顺序理论上也是逐步串行执行但是为了提高性能编译器和处理器常常会对指令做重排序。1) 编译器优化的重排序。编译器在不改变单线程程序语义的前提下可以重新安排语句的执行顺序。2) 指令级并行的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性处理器可以改变语句对应机器指令的执行顺序。3) 内存系统的重排序。由于处理器使用缓存和读/写缓冲区这使得加载和存储操作看上去可能是在乱序执行。从Java源代码到最终实际执行的指令序列会分别经历下面3种重排序happens-before语义从JDK 5开始Java使用新的内存模型使用happens-before的概念来阐述操作之间的内存可见性。那到底什么是happens-before呢在JMM中如果一个操作执行的结果需要对另一个操作可见那么这两个操作之间必须要存在happens-before关系这里提到的两个操作既可以是在一个线程之内也可以是在不同线程之间。happens-before规则如下程序顺序规则 对于单个线程中的每个操作前继操作happens-before于该线程中的任意后续操作。监视器锁规则 对一个锁的解锁happens-before于随后对这个锁的加锁。volatile变量规则 对一个volatile域的写happens-before于任意后续对这个volatile域的读。传递性 如果A happens-before B且B happens-before C那么A happens-before C。注意两个操作之间具有happens-before关系并不意味着前一个操作必须要在后一个操作之前执行happens-before仅仅要求前一个操作(执行的结果)对后一个操作可见且前一个操作按顺序排在第二个操作之前。happens-before与JMM的关系如图所示如图所示一个happens-before规则对应于一个或多个编译器和处理器重排序规则。重排序重排序指的是编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。如果两个操作访问同一个变量且这两个操作中有一个为写操作此时这两个操作之间就存在数据依赖性。数据依赖分为下列3种类型上面情况只要重排序两个操作的执行顺序程序的执行结果就会被改变。而编译器和处理器可能会对操作做重排序但是编译器和处理器在重排序时会遵守数据依赖性编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。注意这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。as-if-serial语义as-if-serial语义的意思是不管怎么重排序单线程程序的执行结果不能被改变。编译器、runtime和处理器都必须遵守as-if-serial语义。所以编译器和处理器不会对存在数据依赖关系的操作做重排序因为这种重排序会改变执行结果。但是如果操作之间不存在数据依赖关系这些操作就可能被编译器和处理器重排序。下面还是以书中的实例(计算圆的面积)进行说明double pi 3.14;// Adouble r 1.0;// Bdouble area pi * r * r; // C上面3个操作的数据依赖关系如图所示A和C之间存在数据依赖关系同时B和C之间也存在数据依赖关系。因此在最终执行的指令序列中C不能被重排序到A和B的前面(因为C排到A和B的前面程序的结果将会被改变)。但A和B之间没有数据依赖关系编译器和处理器可以重排序A和B之间的执行顺序。该程序的两种可能执行顺序as-if-serial语义把单线程程序保护了起来遵守as-if-serial语义的编译器、runtime和处理器共同为编写单线程程序的程序员创建了一个幻觉单线程程序是按程序的顺序来执行的。程序顺序规则根据happens-before的程序顺序规则上面计算圆的面积的示例代码存在3个happens-before关系。1) A happens-before B。2) B happens-before C。3) A happens-before C。而这里的第3个happens-before关系是根据happens-before的传递性推导出来的。注意这里A happens-before B但实际执行时B却可以排在A之前执行JMM并不要求A一定要在B之前执行。JMM仅仅要求前一个操作(执行的结果)对后一个操作可见且前一个操作按顺序排在第二个操作之前。这里操作A的执行结果不需要对操作B可见而且重排序操作A和操作B后的执行结果与操作A和操作B按happens-before顺序执行的结果一致。在这种情况下JMM会认为这种重排序并不非法JMM允许这种重排序。重排序对多线程的影响重排序是否会改变多线程程序的执行结果还是借用书中的一个例子class ReorderExample {int a 0;boolean flag false;public void writer() {a 1; // 1flag true; // 2}public void reader() {if (flag) { // 3int i a * a; // 4}}}flag变量是个标记用来标识变量a是否已被写入。这里假设有两个线程A和BA首先执行writer()方法随后B线程接着执行reader()方法。线程B在执行操作4时能否看到线程A在操作1对共享变量a的写入呢答案是不一定能看到。由于操作1和操作2没有数据依赖关系编译器和处理器可以对这两个操作重排序同样操作3和操作4没有数据依赖关系编译器和处理器也可以对这两个操作重排序。当操作1和操作2重排序时可能会产生什么效果(虚箭线标识错误的读操作用实箭线标识正确的读操作。)如图所示操作1和操作2做了重排序。程序执行时线程A首先写标记变量flag随后线程B读这个变量。由于条件判断为真线程B将读取变量a。此时变量a还没有被线程A写入在这里多线程程序的语义被重排序破坏了当操作3和操作4重排序时会产生什么效果。下面是操作3和操作4重排序后程序执行的时序图在程序中操作3和操作4存在控制依赖关系。当代码中存在控制依赖性时会影响指令序列执行的并行度。为此编译器和处理器会采用猜测执行来克服控制相关性对并行度的影响。以处理器的猜测执行为例执行线程B的处理器可以提前读取并计算a*a然后把计算结果临时保存到一个名为重排序缓冲的硬件缓存中。当操作3的条件判断为真时就把该计算结果写入变量i中。猜测执行实质上对操作3和4做了重排序在这里重排序破坏了多线程程序的语义注意在单线程程序中对存在控制依赖的操作重排序不会改变执行结果。在多线程程序中对存在控制依赖的操作重排序可能会改变程序的执行结果。参考《Java并发编程的艺术》以上就是本文的全部内容希望对大家的学习有所帮助也希望大家多多支持脚本之家。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909781.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!