synchronized是面试中经常会被问到的知识点,相关的问题点也很多,问题答案涉及的知识点也很多,有经验的面试官就会顺着你的答案不断追问一下,下面的对话场景就是相关面试题的连环炮。

面试官:说一下synchronized的作用。
小白:对于单一JVM来说,synchronized可以保证在并发情况下,同一时刻只有一个线程执行某个方法或某段代码,它可用于修饰方法或代码块,实现对同步代码的并发安全控制。

面试官:你刚刚说synchronized可用于修饰方法和代码块,他们有什么区别呢?
小白:修饰方法在底层实现上会在方法访问标识中设置ACC_SYNCHRONIZED标示符,修饰代码块在底层实现上会使用monitorenter和monitorexit指令。

面试官:那你说一下修饰方法方式的底层实现原理?
小白:反编译字节码文件,可以看到在方法的flags中设置了ACC_SYNCHRONIZED访问标识。每个对象都与一个monitor相关联,当且仅当monitor被线程持有时,monitor处于锁定状态。当方法执行时,线程将先尝试获取对象相关联的monitor所有权,然后再执行方法,最后在方法完成(无论是正常执行还是非正常执行)时释放monitor所有权。在方法执行期间,线程持有了monitor所有权,其它任何线程都无法再获得同一个对象相关联的monitor所有权。

上面的答案会引发面试官提问Java对象头和锁相关的问题,需要有心理准备。

面试官:那你再说一下修饰代码块方式的底层实现原理?
小白:反编译字节码文件,可以看到在逻辑代码前添加了monitorenter指令,在逻辑代码尾添加了monitorexit指令。当方法执行时,当前线程执行monitorenter指令尝试获取对象相关联的monitor所有权时,如果此时这个monitor的计数器是0,那么当前线程持有该monitor,同时monitor计数器设置为1;如果当前线程已经持有了对象相关联的monitor所有权,只是想重新获取,那么继续持有该monitor,同时monitor计数器加1;如果有其它线程已经持有了对象相关联的monitor所有权,当前线程阻塞,直到monitor计数器为0,再次尝试获取所有权。方法正常执行或发生异常时,会执行monitorexit指令,释放monitor所有权,monitor计数器减1。

面试官:你刚刚说到了Monitor,能详细再说说吗?
小白:Java虚拟机中,synchronized支持的同步方法和同步语句都是使用monitor来实现的。每个对象都与一个monitor相关联,当一个线程执行到一个monitor监视下的代码块中的第一个指令时,该线程必须在引用的对象上获得一个锁,这个锁是monitor实现的。在HotSpot虚拟机中,monitor是由ObjectMonitor实现,使用C++编写实现,具体代码在HotSpot虚拟机源码ObjectMonitor.hpp文件中。

查看源码会发现,主要的属性有_count(记录该线程获取锁的次数)、_recursions(锁的重入次数)、_owner(指向持有ObjectMonitor对象的线程)、_WaitSet(处于wait状态的线程集合)、_EntryList(处于等待锁block状态的线程队列)。

当并发线程执行synchronized修饰的方法或语句块时,先进入_EntryList中,当某个线程获取到对象的monitor后,把monitor对象中的_owner变量设置为当前线程,同时monitor对象中的计数器_count加1,当前线程获取同步锁成功。

当synchronized修饰的方法或语句块中的线程调用wait()方法时,当前线程将释放持有的monitor对象,monitor对象中的_owner变量赋值为null,同时,monitor对象中的_count值减1,然后当前线程进入_WaitSet集合中等待被唤醒。

面试官:你的回答中说到了锁,那一个对象的锁状态存在哪里?
小白:Java对象的对象头中。

面试官:对象头中包含哪些内容?
小白:一部分是对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称它为“Mark Word”;一部分是类型指针,即是对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例;如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小。

面试官:对对象头中的锁状态标识来说,synchronized属于哪一级别的锁?
小白:重量级锁。

面试官:JVM对锁进行了哪些优化?
小白:......

关注不迷路,记录后端开发那些事

synchronized被这么问,谁能受得了的更多相关文章

  1. synchronized与static synchronized 差异

    1.synchronized与static synchronized 差异       synchronized是对类的当前实例进行加锁,防止其它线程同一时候訪问该类的该实例的全部synchroniz ...

  2. Java 并发:内置锁 Synchronized

    摘要: 在多线程编程中,线程安全问题是一个最为关键的问题,其核心概念就在于正确性,即当多个线程訪问某一共享.可变数据时,始终都不会导致数据破坏以及其它不该出现的结果. 而全部的并发模式在解决问题时,採 ...

  3. synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

    本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁 ...

  4. 看一遍就懂,详解java多线程——volatile

    多线程一直以来都是面试必考点,而volatile.synchronized也是必问点,这里我试图用容易理解的方式来解释一下volatile. 来看一下它的最大特点和作用: 一 使变量在多个线程间可见 ...

  5. 海康威视面试-java应用开发

    一面:技术面 (1)对着简历问本科学过的java相关课程,都学了哪些东西.很懵逼,很早之前学的东西,我都记不清楚了 (2)网络编程相关知识,我也不太懂,就回答了网络协议这块的知识 (3)线程相关,线程 ...

  6. 抛出这8个问题,检验一下你到底会不会ThreadLocal,来摸个底~

    0.问题 和Synchronized的区别 存储在jvm的哪个区域 真的只是当前线程可见吗 会导致内存泄漏么 为什么用Entry数组而不是Entry对象 你学习的开源框架哪些用到了ThreadLoca ...

  7. 面试官:看你简历说写精通ThreadLocal,这几道题你都会吗?

    问题 和Synchronized的区别 存储在jvm的哪个区域 真的只是当前线程可见吗 会导致内存泄漏么 为什么用Entry数组而不是Entry对象 你学习的开源框架哪些用到了ThreadLocal ...

  8. 再有人问你synchronized是什么,就把这篇文章发给他

    在再有人问你Java内存模型是什么,就把这篇文章发给他.中我们曾经介绍过,Java语言为了解决并发编程中存在的原子性.可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronize ...

  9. 面试必问的Synchronized知道这些就可以了

    Synchronized关键字算是Java的元老级锁了,一开始它撑起了Java的同步任务,其用法简单粗暴容易上手.但是有些与它相关的知识点还是需要我们开发者去深入掌握的.比如,我们都知道通过Synch ...

随机推荐

  1. MAVEN(一) 安装和环境变量配置

    一.安装步骤 1.安装maven之前先安装jdk,并配置好环境变量.确保已安装JDK,并 “JAVA_HOME” 变量已加入到 Windows 环境变量. 2.下载maven 进入官方网站下载网址如下 ...

  2. 精心整理(含图版)|你要的全拿走!(R数据分析,可视化,生信实战)

    本文首发于“生信补给站”公众号,https://mp.weixin.qq.com/s/ZEjaxDifNATeV8fO4krOIQ更多关于R语言,ggplot2绘图,生信分析的内容,敬请关注小号. 为 ...

  3. 8.5 NOIP 模拟测试 13

    今天的考试说实话T1很简单没A,我是傻X.T2T3难得一批,但是暴力的分还是拿了! 总结一下就是:骗分过样例,暴力出奇迹!只要瞎搞就行了! 话说现在终于不像之前那么傻了,终于知道打暴力了,因为之前暴力 ...

  4. VLAN的 基本用法与配置

    需求:在一家小型企业中,所有员工都使用一台交换机,老板为了避免员工私下通信,将他们分配了不同网段,但偶尔还是会发现,有些员工会自行修改网段和别人通信.如果你是这家企业的网络工程师,你该如何处理? 1. ...

  5. CentOS7下安装带用户认证的squid服务器(无防火墙)

    1       安装squid服务: yum install squid 安装htpasswd : yum install httpd-tools 2       配置squid配置文件 #该定义需在 ...

  6. hdu 1754 I Hate It (线段树、单点更新)(PS:ios::sync_with_stdio(false)可以加快cin、cout的读取写出速度)

    I Hate ItTime Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. Java :一文掌握 Lambda 表达式

    本文将介绍 Java 8 新增的 Lambda 表达式,包括 Lambda 表达式的常见用法以及方法引用的用法,并对 Lambda 表达式的原理进行分析,最后对 Lambda 表达式的优缺点进行一个总 ...

  8. 分析facebook的AsyncDisplayKit框架中的Transaction的工作原理

    在AsyncDisplayKit框架中有一个_ASAsyncTransaction模块,用于AsyncDiplayNode的异步事务,使用了dispatch_group实现. 主要目的是将operat ...

  9. Linux下的磁盘分区,和创建文件系统(理论及实战)

    首先我们先了解一下磁盘的原理 磁盘的数据结构有: 扇区:盘片被分为多个扇形区域,每一个扇区存放512个字节的数据 磁道:同一个盘片不同半径的同心圆 柱面:不同盘片相同半径构成的圆柱面 公式: 磁盘存储 ...

  10. Java内存模型与volatile关键字

    Java内存模型与volatile关键字 一).并发程序开发 并行程序的开发要涉及多线程.多任务间的协作和数据共享问题. 常用的并发控制:内部锁.重入锁.读写锁.信号量. 二).线程的特点 线程的特点 ...