博客
关于我
Synchronize和Volatile底层实现原理
阅读量:357 次
发布时间:2019-03-04

本文共 2168 字,大约阅读时间需要 7 分钟。

最近在看《并发编程的艺术》这本书,希望能加深对并发领域的理解。书中第二章重点介绍了Java并发机制的底层实现原理,特别是volatile、synchronized以及原子操作等关键机制。本文将围绕这些内容进行详细记录。

1. 上下文切换

在单核或多核处理器中,多线程执行的本质是通过时间片轮-robin机制来实现的。每个线程都能获得一定的CPU时间段来执行任务。当一个任务完成自己的时间片后,就会切换到下一个任务。但在切换前,系统会保存当前任务的状态,以便切换后能够恢复到正确的上下文。

这种状态保存与恢复的过程被称为上下文切换。需要注意的是,上下文切换并非百分之百免费。创建线程、切换线程状态等操作都需要一定的开销,甚至在某些情况下,线程切换比单线程执行还要慢。这也说明并发编程并不是简单的快与慢的问题。

减少上下文切换的方法

为了减少上下文切换的开销,可以采用以下策略:

  • 无锁并发编程:通过将任务分成独立的段处理,每个线程负责特定的数据段。这种方法可以避免锁竞争带来的线程切换开销。

  • 使用CAS算法:Java的Atomic包中的CAS操作可以在不加锁的情况下进行原子性更新,减少线程切换的开销。

  • 优化线程数量:避免过度创建线程。特别是当任务量稀少时,过多的线程可能会导致大部分线程处于等待状态。

  • 协程:协程是一种在单线程内通过调度实现多任务并行的方式,能够在不引入线程切换的前提下实现并发。

  • 2. volatile关键字

    volatile关键字在Java中具有特殊的内存模型特性。任何访问volatile变量的线程都能看到该变量的最新值。这是因为volatile变量的写操作会触发缓存一致性机制,确保所有线程能够看到一致的值。

    volatile的实现原理

    当一个volatile变量进行写操作时,JVM会在生成的机器指令中插入Lock前缀指令。这个指令的作用是:

  • 写回内存:将处理器缓存中的数据写回系统内存。

  • 缓存锁定:使用缓存一致性机制,确保其他处理器在读取该内存地址时会发现缓存无效,从而必须重新从内存读取最新数据。

  • 这种机制保证了volatile变量的可见性和一致性,避免了多线程竞读或写入带来的数据不一致问题。

    3. synchronized的实现原理

    synchronized在Java中通过Monitor对象实现方法和代码块的同步。具体来说:

    • 代码块同步:使用monitorentermonitorexit指令。monitorenter会在进入同步代码块时尝试获取Monitor对象的所有权,monitorexit则会在退出时释放Monitor对象的所有权。

    • 方法同步:在方法执行和异常处插入monitorentermonitorexit指令,确保方法执行时的同步性。

    JVM会为每个对象分配一个Monitor对象。当一个线程尝试进入同步代码块时,会请求Monitor的所有权。如果Monitor已经被持有,JVM会等待当前持有Monitor的线程释放锁,才能继续执行。

    3.1 Java对象头

    synchronized锁是存在于Java对象头中的。Java对象头由以下三部分组成:

  • Mark Word:用于标记对象的状态,包括是否为活性对象、是否为偏向锁等信息。

  • 指向类的指针:指向类的Class对象,用于垃圾回收等场景。

  • 数组长度:对于数组对象,存储数组的长度。

  • 在深入理解synchronized机制之前,了解对象头的结构是非常重要的。

    3.2 锁的升级与对比

    在Java SE 1.6中,锁被进一步优化为四种状态:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。这些状态会根据竞争情况自动升级。

    偏向锁

    偏向锁是为减少锁的获取和释放代价而引入的。在大多数情况下,锁的竞争非常少,甚至可能只在同一个线程之间进行。偏向锁通过在栈帧中存储偏向锁的线程ID来减少锁的获取和释放开销。

    轻量级锁

    轻量级锁在竞争激烈时会升级为重量级锁。轻量级锁的加锁和解锁是通过循环CAS实现的。具体来说:

    • 加锁:尝试使用CAS将Mark Word替换为锁记录的指针。如果成功,线程获得锁;如果失败,线程会自旋直到成功。

    • 解锁:尝试将锁记录的指针替换回Mark Word。如果成功,锁被释放;如果失败,锁会膨胀为重量级锁。

    锁的优缺点

    锁的实现机制虽然高效,但也有其局限性。重量级锁的获取和释放开销较大,且锁竞争会导致线程等待。轻量级锁虽然减少了锁的获取和释放开销,但在竞争激烈时会升级为重量级锁,增加了调度开销。

    4. 原子操作的实现原理

    原子操作是保证多个操作原子性完成的关键机制。在处理器层面,原子操作主要通过总线锁和缓存锁实现。

    处理器层面的实现

  • 总线锁:通过LOCK#信号确保在总线上独占内存访问。

  • 缓存锁:在缓存一致性机制的帮助下,确保缓存操作的原子性。

  • Java中的原子操作可以通过循环CAS实现。CAS操作虽然简单,但也面临着ABA问题、自旋开销大以及只能操作单个变量等挑战。

    Java如何实现原子操作

    对于多个共享变量的原子操作,Java通常会使用锁机制。对于单个共享变量,JVM可以通过循环CAS实现原子操作。这种实现方式既保证了原子性,又尽量减少了锁的使用。

    参考

    本文内容主要参考自《Java并发编程的艺术》。

    转载地址:http://xgdr.baihongyu.com/

    你可能感兴趣的文章
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
    查看>>
    NHibernate学习[1]
    查看>>
    NHibernate异常:No persister for的解决办法
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
    查看>>
    NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
    查看>>
    NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
    查看>>
    NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
    查看>>
    NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
    查看>>
    NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
    查看>>