• 面试连环炮系列(三):synchronized怎么用的


    1. synchronized怎么用的?
      用过,synchronized是常用的并发控制关键字,简单的说就是访问加锁。它可以修饰静态方法或者一个类的class对象,这叫类锁;可以修饰普通方法或者代码块,这叫对象锁。

    2. synchronized是可重入锁吗?
      从互斥锁的设计上来说,当一个线程试图操作一个由其他线程持有的对象锁的资源时,将会处于阻塞状态,但当一个线程再次请求自己持有对象锁的资源时,这种情况属于重入锁,请求将会成功。java中synchronized是基于原子性的内部锁机制,是可重入的。

    3. synchronized的实现原理了解过吗?
      synchronized使用了monitorenter和monitorexit指令实现同步,这两个指令本质上都是对一个对象的监视器(monitor)进行获取。这个过程是排他的,同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权。

    4. 能说说synchronized的锁升级吗?
      jdk1.6以后对synchronized的锁进行了优化,锁的级别从低到高逐步升级:无锁->偏向锁->轻量级锁->重量级锁。但是锁的升级是单向的,只能从低到高升级,不会降级。JVM中对象在内存中的布局分为三块区域:对象头、实例变量和填充数据。对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)。Mark Word用于存储对象自身的运行时数据,它是实现轻量级锁和偏向锁的关键。

      1. 如果一个线程获得了锁,锁就进入偏向模式,此时Mark Word的结构变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作,这样就省去了大量有关锁申请的操作,提高了程序的性能。
      2. 在锁竞争激烈的场合,每次申请锁的线程都是不相同的,偏向锁就失效了,偏向锁失败后升级为轻量级锁。轻量级锁是相对于使用操作系统互斥量来实现的传统锁而言的,它所适应的场景是线程交替执行同步块,如果存在同一时间访问同一锁的情况,就会膨胀为重量级锁。
      3. 轻量级锁失败后,还会进行自适应自旋。大多数情况下线程持有锁的时间都不会太长,如果操作系统层面直接挂起,线程之间的切换时需要从用户态转换到核心态,这个状态的转换需要比较长的时间。自旋锁假设在当前的线程很快可以获得锁,虚拟机会让当前线程做50个循环或100循环空循环。在经过若干次循环后,如果得到锁就顺利进入临界区。如果还不能获得锁就会将线程挂起,升级为重量级锁了。注意,JVM还会自动调整自旋次数,这次成功了,下次自旋的次数会多;如果失败了,下次自旋的次数就会减少。

    参考文章:

    https://blog.csdn.net/u011212394/article/details/82228321
    https://www.cnblogs.com/fuly550871915/p/4890753.html
    https://www.cnblogs.com/paddix/p/5405678.html

    鸡汤:不要因为走得太远,忘了我们为什么出发。— 纪伯伦

  • 相关阅读:
    <转>修正版 疯狂代码 写给WEB2.0的站长
    一组MSSQL千万数量级分页存储过程
    flash AS +xml 加载图片(使用MovieClipLoader实现LOADING)
    [转]优化SQL Server的内存占用之执行缓存
    日志记录组件[Log4net]详细介绍(转)
    IBatis.Net如何支持多个数据库 [转帖]
    c#导入导出EXCEL
    弄了个新blogs 欢迎捧场
    ActionSrcipt 资源
    一个鼠标拖出一个圆形的简单demo
  • 原文地址:https://www.cnblogs.com/xiaoyangjia/p/11457994.html
Copyright © 2020-2023  润新知