zoukankan      html  css  js  c++  java
  • 并发编程-锁相关的内存语义

    锁的内存语义本质上可以说是对共享变量的更新,能及时让其他线程观察到;并且通过内存屏障,组织编译器或处理器指令重排序,导致多线程下不一致的现象。

    1. volatile内存语义

      见上一篇文章。

    2. 锁的内存语义

    (1)锁的释放和获取的内存语义

      当线程释放锁时,JMM会将本地内存中的共享变量同步到主内存中;

      当线程获取锁时,JMM会将该线程对应的本地内存置为无效,从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。

    (2)锁内存语义的实现

      ReentrantLock的实现依赖于AbstractQueuedSynchronizer(AQS),AQS使用一个整形的volatile变量(state)来维护同步状态。这个volatile变量是ReentrantLock实现的关键。

      编译器不会对volatile读与其后的任意内存操作重排序不会对volatile写与其前的任意操作重排序。CAS同时具有volatile读和写的内存语义,编译器不会对CAS前和后的任意内存操作重排序,其是通过底层处理器缓存锁定实现原子性的。

    CAS同时具有volatile读和写的内存语义,故Java线程之间的通信存在4种方式:

      ① A线程写volatile变量,随后B线程读该变量;

      ② A线程写volatile变量,随后B线程使用CAS更新该变量;

      ③ A线程使用CAS更新volatile变量,随后B线程使用CAS更新该变量;

      ④ A线程使用CAS更新volatile变量,随后B线程读该变量。

    concurrent包的实现,通用的实现模式:

      ① 声明共享变量为volatile

      ② 使用CAS的原子条件更新来实现线程之间的同步

      ③ 配合以volatile的读/写,及CAS所具有的volatile读和写的内存语义来实现线程间的通信。 

    AQS、非阻塞数据结构和原子变量类,都是使用该模式来实现的。(该图摘自java concurrent包的实现原理

    3. final内存语义

    (1)final重排序规则

      ① 在类实例化时,构造函数中对一个final域的写入,与后边对该类对象的引用之间不能重排序。防止引用到未初始化完全的对象

      首先对象是共享对象如通过static修饰的类实例。JMM禁止编译器将final域的写重排序到构造函数之外;编译器会在final域写入之后,构造函数返回之前插入StoreStore屏障。

      对于普通变量的赋值可能重排序到构造函数之外,此时另一个线程通过该对象访问普通变量时,可能还没有赋值。(具体实例参看《Java并发编程的艺术》)

      ②  初次读一个包含final域的对象,与初次读这个final域之间不能重排序。防止对象引用提前读,而对象还未初始化完全

      在读对象引用和对象final域时,JMM在两者之间插入LoadLoad屏障,禁止读final域重排序到对象引用前边,普通变量可能存在这种情况。

      ③ 对final域是数组或对象等引用类型的情况,有如下约束:在构造函数内对一个final引用的对象的成员域的写入,与随后对该类对象的引用之间不能重排序。

      即final引用的对象中所有成员都写完成后,才可以被其他线程引用。

    (2)禁止在构造函数中将this复制给外边的对象引用,否则可能导致其他线程看到初始化不完全的实例。

  • 相关阅读:
    linux进程调度策略(SCHED_OTHER,SCHED_FIFO,SCHED_RR)
    10、单机运行环境搭建之 --Windows下mysqldump 备份与还原数据库
    5、单机运行环境搭建之 --CentOS6.4拷贝Tomcat7形成集群
    9、单机运行环境搭建之 --CentOS6.4下mysqldump 备份与还原数据库
    7、单机运行环境搭建之 --CentOS6.4安装Memcached
    13、单机运行环境搭建之 --Centos6.4下iptables保护主机安全
    12、单机运行环境搭建之 --Centos6.4下webbench压力测试
    6、单机运行环境搭建之 --CentOS6.4安装MySQL 5.6.10并修改MySQL的root用户密码
    4、单机运行环境搭建之 --CentOS6.5优化Tomcat7
    8、单机运行环境搭建之 --CentOS6.4安装vsftpd
  • 原文地址:https://www.cnblogs.com/shuimuzhushui/p/11336130.html
Copyright © 2011-2022 走看看