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

Java高并发编程:3----Synchronized

阅读更多

1 引言

在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁,以及锁的存储结构和升级过程。

2 术语定义

术语 英文 说明
CAS Compare and Swap

比较并设置。用于在硬件层面上提供原子性操作。

在Intel 处理器中,比较并交换通过指令cmpxchg实现。

比较是否和给定的数值一致,如果一致则修改,不一致则不修改。

3 同步的基础

Java中的每一个对象都可以作为锁。

  • 对于同步方法,锁是当前实例对象。
  • 对于静态同步方法,锁是当前对象的Class对象。
  • 对于同步方法块,锁是Synchonized括号里配置的对象。

当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。那么锁存在哪里呢?锁里面会存储什么信息呢?

4 同步的原理

JVM规范规定JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。代码块同步是使用monitorenter和monitorexit指令实现,而方法同步是使用另外一种方式实现的,细节在JVM规范里并没有详细说明,但是方法的同步同样可以使用这两个指令来实现。monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处, JVM要保证每个monitorenter必须有对应的monitorexit与之配对。任何对象都有一个 monitor 与之关联,当且一个monitor 被持有后,它将处于锁定状态。线程执行到 monitorenter 指令时,将会尝试获取对象所对应的 monitor 的所有权,即尝试获得对象的锁。

4.1 Java对象头

锁存在Java对象头里。如果对象是数组类型,则虚拟机用3个Word(字宽)存储对象头,如果对象是非数组类型,则用2字宽存储对象头。在32位虚拟机中,一字宽等于四字节,即32bit。

Java对象头里的Mark Word里默认存储对象的HashCode,分代年龄和锁标记位。32位JVM的Mark Word的默认存储结构如下


在运行期间Mark Word里存储的数据会随着锁标志位的变化而变化。Mark Word可能变化为存储以下4种数据:


 在64位虚拟机下,Mark Word是64bit大小的,其存储结构如下: 

 4.2 锁的升级

Java SE1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”,所以在Java SE1.6里锁一共有四种状态,无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率,下文会详细分析。

4.3 偏向锁

Hotspot的作者经过以往的研究发现大多数情况下锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要花费CAS操作来加锁和解锁,而只需简单的测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁,如果测试成功,表示线程已经获得了锁,如果测试失败,则需要再测试下Mark Word中偏向锁的标识是否设置成1(表示当前是偏向锁),如果没有设置,则使用CAS竞争锁,如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。

偏向锁的撤销:偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。偏向锁的撤销,需要等待全局安全点(在这个时间点上没有字节码正在执行),它会首先暂停拥有偏向锁的线程,然后检查持有偏向锁的线程是否活着,如果线程不处于活动状态,则将对象头设置成无锁状态,如果线程仍然活着,拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark Word要么重新偏向于其他线程,要么恢复到无锁或者标记对象不适合作为偏向锁,最后唤醒暂停的线程。下图中的线程1演示了偏向锁初始化的流程,线程2演示了偏向锁撤销的流程。

关闭偏向锁:偏向锁在Java 6和Java 7里是默认启用的,但是它在应用程序启动几秒钟之后才激活,如有必要可以使用JVM参数来关闭延迟-XX:BiasedLockingStartupDelay = 0。如果你确定自己应用程序里所有的锁通常情况下处于竞争状态,可以通过JVM参数关闭偏向锁-XX:-UseBiasedLocking=false,那么默认会进入轻量级锁状态。

4.4 轻量级锁

轻量级锁加锁:线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。

轻量级锁解锁:轻量级解锁时,会使用原子的CAS操作来将Displaced Mark Word替换回到对象头,如果成功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。下图是两个线程同时争夺锁,导致锁膨胀的流程图。

因为自旋会消耗CPU,为了避免无用的自旋(比如获得锁的线程被阻塞住了),一旦锁升级成重量级锁,就不会再恢复到轻量级锁状态。当锁处于这个状态下,其他线程试图获取锁时,都会被阻塞住,当持有锁的线程释放锁之后会唤醒这些线程,被唤醒的线程就会进行新一轮的夺锁之争。

5 锁的优缺点对比


 

 转子:http://www.infoq.com/cn/articles/java-se-16-synchronized

  • 大小: 77.6 KB
  • 大小: 43.4 KB
  • 大小: 85.5 KB
  • 大小: 66.3 KB
  • 大小: 27.2 KB
  • 大小: 213.6 KB
  • 大小: 246.5 KB
  • 大小: 162.6 KB
分享到:
评论
3 楼 世界尽头没有你 2018-05-10  
Java并发编程与高并发解决方案
网盘地址:https://pan.baidu.com/s/1sFpDC81emps9fH3xcUHhfw 密码: nrrf
备用地址(腾讯微云):https://share.weiyun.com/5grRNnM 密码:e324w9
2 楼 叮咚可乐名 2018-04-19  
Java并发编程与高并发解决方案
网盘地址1:https://pan.baidu.com/s/1oCUiKQYcHRM6jUBpGAh8hQ 密码: 4qjh
网盘地址2:https://pan.baidu.com/s/1_1AFpCZ-BAAR_LnE97PLeA 密码: xzwh
网盘地址3:https://pan.baidu.com/s/1J8gn_6VKcuWWMUoPkYbm-g 密码: hr8k
备用地址(腾讯微云):https://share.weiyun.com/5grRNnM 密码:e324w9
1 楼 叮咚可乐名 2018-04-12  
Java并发编程和高并发解决方案视频课程
网盘地址:https://pan.baidu.com/s/19tUBliZIYy2HQ0LiVfCw-A 密码: d9fb
备用地址(腾讯微云):https://share.weiyun.com/5grRNnM 密码:e324w9

学会高并发处理思路与手段,让跳槽面试从容不迫,并发与高并发是面试的重要考察点,常问面试问题与答案都在这里了!

无论面试还是实际开发,几乎都会涉及并发相关知识及高并发相关场景处理,如果你想系统的学习一下并发编程
并了解一下实际的高并发场景及应对方案,那这门课就是为你准备的。

相关推荐

    Java并发编程:设计原则与模式(第二版)-3

    《Java并发编程:设计原则与模式(第二版)》是一本深入探讨Java多线程编程技术的权威著作。这本书详细阐述了在Java平台中进行高效并发处理的关键概念、设计原则和实用模式。以下是对该书内容的一些核心知识点的概述...

    java并发编程:设计原则与模式.rar

    《Java并发编程:设计原则与模式》是一本深入探讨Java多线程编程的书籍,它涵盖了并发编程中的关键概念、原则和模式。在Java中,并发处理是优化应用程序性能、提高资源利用率的重要手段,尤其在现代多核处理器的环境...

    Java并发编程:设计原则与模式(第二版)-3PDF

    《Java并发编程:设计原则与模式(第二版)》是一本深入...以上知识点构成了《Java并发编程:设计原则与模式(第二版)》的主要内容,通过学习和实践这些知识,开发者可以更好地设计和实现高并发、高性能的Java应用。

    java高级技术JUC高并发编程教程2021(1.5G)

    java高级技术JUC高并发编程教程2021(1.5G) 〖课程介绍〗: java高级技术JUC高并发编程教程2021(1.5G) 〖课程目录〗:   01-JUC高并发编程-课程介绍.mp4 02-JUC高并发编程-JUC概述和进程线程概念(1).mp4 03-JUC...

    Java 并发核心编程

    3. **ConcurrentLinkedQueue**: 提供了一个基于链表的无界队列实现,适用于高并发场景。 #### 五、线程协作 线程之间的协作是多线程编程中的另一个关键方面,涉及到线程之间的通信和同步。Java提供了多种机制来...

    Java并发编程:Synchronized关键字深度解析

    本文深入探讨了Java中用于解决并发...通过对synchronized关键字的深入分析,本文为Java开发者提供了对并发编程中关键同步工具的全面理解,特别是在高并发场景下如何有效使用synchronized以确保线程安全和提高程序性能。

    java高并发编程第一版

    《Java高并发编程》第一版是一本专注于Java平台上的并发编程技术的专业书籍。在Java开发领域,高并发编程是至关重要的技能,特别是在大型分布式系统、云计算以及互联网应用中。本书旨在帮助开发者理解和掌握如何在...

    深入理解高并发编程-核心技术原理

    【深入理解高并发编程-核心技术原理】是一本专注于讲解高并发编程核心概念和技术的书籍,由阿里P8级别的架构师及Mykit系列开源框架作者撰写。本书内容涵盖源码分析、基础案例、实战案例和面试相关知识,旨在帮助读者...

    JAVA并发编程实践-中文-高清-带书签-完整版

    最后,本书还涵盖了Java并发编程的最新发展,如Fork/Join框架和Parallel Streams,这些是Java 7及以后版本引入的新特性,能够帮助开发者充分利用多核处理器的优势,编写出高性能的并行代码。 总而言之,《JAVA并发...

    java高并发程序设计(原版电子书)

    《Java高并发程序设计》是一本深入探讨Java平台上的并发编程技术的专业书籍,由葛一鸣等人编著。这本书旨在帮助读者理解并掌握在高并发环境下编写高效、稳定且可扩展的Java应用程序的关键技巧和最佳实践。以下是该书...

    Java并发编程实践-电子书-07章

    深入地探讨Java并发编程实践中的显示锁概念,我们聚焦于《Java并发编程实践-电子书-07章》所提供的丰富内容。本章着重于展示如何使用显示锁(也称为高级锁),并详细介绍了Lock和ReentrantLock接口以及它们在并发...

    java高并发编程推荐超好的一本电子书

    根据提供的信息,我们可以深入探讨Java高并发编程的相关知识点。高并发是现代软件系统设计中一个非常重要的方面,尤其是在云计算和大数据处理领域。下面将详细解释Java高并发编程的基础概念、核心技术以及实现技巧。...

    JAVA并发编程实践JavaConcurrencyinPractice-中文-高清-带书签-完整版Doug Lea 等著

    通过对这些知识点的学习,读者可以全面掌握Java并发编程的核心技术和最佳实践,为开发高性能、高可靠性的并发应用程序打下坚实的基础。无论是初学者还是有经验的开发者,都能从本书中获得宝贵的知识和技能。

    Java并发编程:设计原则与模式2中文版

    《Java并发编程:设计原则与模式2中文版》是一本深度探讨Java开发中并发编程的专著,旨在帮助开发者理解和掌握在多线程环境下编写高效、安全、可维护的代码。这本书涵盖了Java并发编程的核心概念、最佳实践以及常用...

    Java并发编程实践-电子书-03章

    ### Java并发编程实践-电子书-03章知识点解析 #### 3.1 java.util.concurrent概述 `java.util.concurrent`包是在JDK5.0之后引入的,它为多线程编程提供了强大的支持,旨在更好地利用现代多处理器或多核系统的性能...

    Java并发编程实践--电子书.rar

    《Java并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。...通过阅读这本书,你可以深入理解Java并发编程的理论和实践,提升你的编程能力,为构建高并发、高性能的系统打下坚实基础。

    实战Java高并发程序设计-随书代码

    《实战Java高并发程序设计》是一本专注于Java并发编程实践的书籍,随书代码提供了大量示例,帮助读者深入理解并掌握在实际开发中如何处理高并发场景下的问题。本书的核心知识点涵盖了Java并发编程的基础理论、核心...

    Java并发编程实践-电子书1-9章pdf

    3. **第三章:并发工具类** - 本章可能会详细介绍Java并发包(java.util.concurrent)中的工具类,如ExecutorService、Future、Callable、Semaphore、CyclicBarrier、CountDownLatch等,这些工具极大地简化了并发...

Global site tag (gtag.js) - Google Analytics