• Java一致性的实现


    一致性

     

     

    内存模型

    每一个线程有一个工作内存和主存独立

    工作内存存放主存中变量的值的拷贝

     

     

    Happen Before

    • 1、程序次序规则:在一个单独的线程中,按照程序代码的执行流顺序,(时间上)先执行的操作happen—before(时间上)后执行的操作。
    • 2、管理锁定规则:一个unlock操作happen—before后面(时间上的先后顺序,下同)对同一个锁的lock操作。
    • 3、volatile变量规则:对一个volatile变量的写操作happen—before后面对该变量的读操作。
    • 4、线程启动规则:Thread对象的start()方法happen—before此线程的每一个动作。
    • 5、线程终止规则:线程的所有操作都happen—before对此线程的终止检测,可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行。
    • 6、线程中断规则:对线程interrupt()方法的调用happen—before发生于被中断线程的代码检测到中断时事件的发生。
    • 7、对象终结规则:一个对象的初始化完成(构造函数执行结束)happen—before它的finalize()方法的开始。
    • 8、传递性:如果操作A happen—before操作B,操作B happen—before操作C,那么可以得出A happen—before操作C。

     

     

    当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作

    每一个操作都是原子的,即执行期间不会被中断

    对于普通变量,一个线程中更新的值,不能马上反应在其他变量中

    如果需要在其他线程中立即可见,需要使用 volatile 关键字

    CAS(Compare And Swap)

    非阻塞同步指令之一,硬件指令集支持。先进行操作,如果有并发操作,则不断重试直到成功。

     

     

    final不可变

    作用于类、方法、成员变量、局部变量。初始化完成后的不可变对象,其它线程可见。常量不会改变不会因为其它线程产生影响。Final修饰的引用类型的地址不变,同时需要保证引用类型各个成员和操作的线程安全问题。因为引用类型成员可能是可变的。

     

    synchronized同步

    作用域代码块、方法上。通过线程互斥,同一时间的同样操作只允许一个线程操作。通过字节码指令实现。

    Volatile

    1. volatile 修饰的变量的变化保证对其它线程立即可见。

      volatile变量的写,先发生于读。每次使用volatile修饰的变量个线程都会刷新保证变量一致性。但同步之前各线程可能仍有操作。如:各个根据volatile变量初始值分别进行一些列操作,然后再同步写赋值。每个线程的操作有先后,当一个最早的线程给线程赋值时,其它线程同步。但这时其它线程可能根据初始值做了改变,同步的结果导致其它线程工作结果丢失。

      根据volatile的语意使用条件:运算结果不依赖变量的当前值。

    2. volatile禁止指令重排优化。

      这个语意导致写操作会慢一些。因为读操作跟这个没关系。

       

      并发包概述

      java.util.concurrent 包含许多线程安全、测试良好、高性能的并发构建块。不客气地说,创建java.util.concurrent 的目的就是要实现 Collection 框架对数据结构所执行的并发操作。通过提供一组可靠的、高性能并发构建块,开发人员可以提高并发类的线程安全、可伸缩性、性能、可读性和可靠性。

      此包包含locks,concurrent,atomic 三个包。

      Atomic:原子数据的构建。

      Locks:基本的锁的实现,最重要的AQS框架和lockSupport

      Concurrent:构建的一些高级的工具,如线程池,并发队列等。

      其中都用到了CAScompare-and-swap)操作。CAS 是一种低级别的、细粒度的技术,它允许多个线程更新一个内存位置,同时能够检测其他线程的冲突并进行恢复。它是许多高性能并发算法的基础。在 JDK 5.0 之前,Java 语言中用于协调线程之间的访问的惟一原语是同步,同步是更重量级和粗粒度的。公开 CAS 可以开发高度可伸缩的并发 Java 类。这些更改主要由 JDK 库类使用,而不是由开发人员使用。

      CAS操作都封装在java 不公开的类库中,sun.misc.Unsafe。此类包含了对原子操作的封装,具体用本地代码实现。本地的C代码直接利用到了硬件上的原子操作。

       

  • 相关阅读:
    (14)python函数与变量
    ①③python中的字符串与字符编码
    ①②python文件操作及文件增删改查
    rsa公钥私钥
    MySQL创建数据库和表
    Rsync + Innotify 部署实例
    LNMPT部署示例
    Nginx 调优
    Nginx 二进制方式安装
    wget & curl 命令
  • 原文地址:https://www.cnblogs.com/jiumao/p/7136631.html
Copyright © 2020-2023  润新知