`
woodding2008
  • 浏览: 289522 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java重排序

 
阅读更多

 

        重排序是指编译器和处理为了优化程序性能而对指令序列进行重新排序的一种手段。

数据依赖

        如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。数据依赖分为下列3中类型。

名称 代码示例 说明
写后读 a=1;b=a; 写一个变量之后,再读这个位置
写后写 a=1;a=2; 写一个变量之后,再写这个变量
读后写 a=b;b=1; 读一个变量之后,再写这个变量
         上面的3中情况,只要重排序两个操作的执行顺序,程序的执行结果就会被改变。编译器和处理器在重新排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。数据依赖仅针对处理器中执行的指令序列和单个线程中执行的操作,不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。

as-if-serial语义

        as-if-serial语义的意思是:不管怎么重排序程序的执行结果不能被改变。编译器、runtime和处理器必须都遵守as-if-serial语义。如果操作之间不存在数据依赖关系,这些操作就可能被编译器和处理器重新排序。下面是计算圆面积的示例。
double pi = 3.14;       //A
double r = 1.0;          //B
double area = pi * r;  //C
 A和C之间存在数据依赖关系,同时B和C之间也存在数据依赖关系。因此C不能排在A和B的前面,但A和B没有依赖关系,编译器就可以重新排序A和B之间的执行顺序。

程序顺序规则

       根据happens-before的程序顺序规则,上面计算圆面积的代码存在3个happens-before关系。
1) A happens-before B
2) B happens-before C
3) A happens-before C
        

重排序对多线程的影响

         重排序是否会改变多线程程序的执行结果。
class ReorderExample{
       int a = 0;
       boolean flag = false;
       
       public void writer(){
           a = 1;            //1
           flag = true;      //2
      }

       public void reader(){
             if(flag){      //3
                 int i= a*a;//4
                 ...
              }
       }
}
        flag变量是个标记,用来标识变量a是否已被写入。这里假设有两个线程A和B,A首先执行writer()方法,随后B线程执行reader()方法。线程B在执行操作4时,能否看到线程A在操作1对共享变量a的写入吗?
        不一定能看到。
         由于操作1和操作2没有数据依赖关系,编译器和处理器可以对这两个操作重排序,同样3和4没有数据依赖关系,编译器也可以对这两个操作重排序。
         操作1和操作2做了重排序,线程A首先标记变量flag,随后B线程读取这个变量,由于条件为true,线程B读取变量a,此时变量a还没有写入,这里多线程程序的语义被破坏了。
        操作3和操作4存在控制依赖关系。代码存在控制依赖关系时,会影响指令程序的并行度。
 
感谢并发编程网ticmy提供的中文版:
http://www.ticmy.com/?p=315
http://ifeve.com/wp-content/uploads/2014/03/JSR133%E4%B8%AD%E6%96%87%E7%89%881.pdf
分享到:
评论

相关推荐

    java中文排序,数字字母汉字排序

    在Java编程语言中,对包含中文、数字和字母的数据进行排序是一项常见的任务。这个场景下,我们关注的是如何实现一个自定义的排序规则,按照数字、字母和汉字的顺序进行排列。以下是对这一主题的详细解释。 首先,...

    Java 实现ip 地址排序

    Java ip 地址排序Java ip 地址排序Java ip 地址排序Java ip 地址排序

    java冒泡排序代码

    java冒泡排序代码,亲测能用,控制台输入数据,自动排序

    java 中文姓氏 排序

    ### Java 中文姓氏排序详解 #### 一、引言 在处理中文数据时,我们经常需要对含有中文姓名的数据进行排序。Java 提供了多种方式进行排序,包括使用 `Collections.sort()` 方法配合自定义比较器(`Comparator`)。...

    java基础冒泡排序.ppt

    Java基础知识: 冒泡排序详解,简单而详细的讲清楚了,什么是冒泡排序。 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如...

    java数组排序

    在Java编程语言中,数组排序是一项基础且重要的任务。它涉及到不同的算法,这些算法通过比较和交换元素来达到数组元素的有序状态。本篇将详细探讨几种常见的排序算法及其在Java中的实现。 首先,让我们从最简单的...

    JAVA 8种排序介绍及实现

    本文将介绍两种常见的排序算法:直接插入排序和希尔排序,并通过Java代码实现来帮助理解。 1. 直接插入排序(直接插入排序) 直接插入排序是一种简单的排序方法,它的工作原理类似于我们平时手动整理扑克牌。在排序...

    java List 排序 Collections.sort

    总结起来,`Collections.sort()`是Java中对List进行排序的标准工具,它支持自然排序和自定义排序。了解其工作原理和优化技巧,可以帮助我们在编程实践中更高效地处理数据。通过阅读和理解`Collections.sort()`的源码...

    java冒泡排序java冒泡排序集锦方法!

    以上三个知识点总结了关于 Java 排序的一些基本应用,包括基础的冒泡排序算法、使用标准库 `Collections.sort()` 进行排序以及使用 `RuleBasedCollator` 实现国际化排序等。这些技术对于编写高效、可维护的 Java ...

    java排序.txt

    根据提供的文件信息,我们可以归纳出以下关于Java排序的相关知识点: ### 一、文件基本信息 - **文件名**:`java排序.txt` - **文件描述**:该文本文件主要介绍了几种常用的Java排序算法,并通过示例代码展示了...

    java 集合分组与排序

    下面我们将深入探讨如何在Java中实现集合的分组与排序。 1. **集合分组**: 集合分组通常涉及到`GroupingBy`操作,这在Java 8引入的流(Stream)API中得到了很好的支持。`Collectors.groupingBy`方法允许我们将...

    Java 选择排序 算法

    Java选择排序算法是一种简单直观的排序算法,它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。这种算法对列表中的数据进行了一次完整...

    JAVA排序汇总 各种排序

    在Java编程语言中,排序是数据处理中非常基础且重要的操作。本文将全面解析Java中的各种排序算法,帮助你理解并掌握它们的核心概念、实现方式以及适用场景。 1. 冒泡排序(Bubble Sort) 冒泡排序是最简单的排序...

    java 选择排序法

    在Java中实现选择排序,我们通常会用到数组这一数据结构。 首先,我们要理解Java中的数组。数组是一种线性数据结构,它将相同类型的元素存储在连续的内存位置中,通过索引来访问这些元素。在Java中,声明数组时需要...

    java数组自定义排序

    java中数组的自定义排序,种类繁多,简单实现,可自由操控。

    java实现归并排序

    Java实现归并排序 Java 实现归并排序是一种常用的排序算法,通过分治策略将原始数组分成小组,然后对每个小组进行排序,最后将排序好的小组合并成一个有序数组。下面是 Java 实现归并排序的知识点总结: 基本思想 ...

    JAVA冒泡排序和快速排序算法

    在编程领域,排序算法是数据结构与算法学习中的基础部分,尤其在JAVA中,掌握不同的排序算法对于提高程序效率至关重要。本节将深入探讨两种常见的排序算法:冒泡排序和快速排序。 首先,我们来详细讲解冒泡排序。...

Global site tag (gtag.js) - Google Analytics