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. 通过Value获取Map中的键值Key的四种方法

    1 简介 我们都知道Map是存放键值对<Key,Value>的容器,知道了Key值,使用方法Map.get(key)能快速获取Value值.然而,有的时候我们需要反过来获取,知道Value ...

  2. Elasticsearch6.x集群部署

    一.准备阶段 三台ubuntu系统机器 ip 计算机名 192.168.2.132 master 192.168.2.133 slave1 192.168.2.134 slave2 下载: jdk-8 ...

  3. Consul安装集群搭建

    1 consul的安装和配置 1.1 consul agent 命令介绍 下载consul_1.0.0_linux_amd64.zip解压,里面只有一个consul可执行文件,其中,consul最常用 ...

  4. sqlite修改表、表字段等与sql server的不同之处

    sqlite中只支持 ALTER TABLE 命令的 RENAME TABLE 和 ADD COLUMN. 其他类型的 ALTER TABLE 操作如 DROP COLUMN,ALTER COLUMN ...

  5. php的精度计算问题(bcadd和bcsub)

    一.前言 我们在进行php开发的时候经常会遇到浮点型的问题,特别是涉及金额的部分,常常需要进行加减运算.当小数点的位数比较多的时候,往往容易犯一些很低级的错误.这里记录一下php的精度计算和封装的小d ...

  6. VMware安装Ubuntu 16.04.4 LTS

    1.下载Ubuntu镜像 https://www.ubuntu.com/download/desktop 2.创建新的虚拟机 3. 4.这里默认即可,可以不选 5. 6. 7.这里位置可以随时改 8. ...

  7. lqb 基础练习 杨辉三角形

    基础练习 杨辉三角形 时间限制:1.0s   内存限制:256.0MB     问题描述 杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数. 它的一个重要性质是:三角形中的 ...

  8. python:类1——类和对象基础

    一.OO = Object Oriented 面向对象 OOP面向对象编程.OOA面向对象分析.OOD面向对象设计 二.属性+方法——>类(数据和函数) class Turtle(): #类名约 ...

  9. this绑定方式总结

    最近在回顾js的一些基础知识,把<你不知道的js>系列又看了一遍,this始终是重中之重,还是决定把this相关知识做一个系统的总结,也方便自己日后回顾. this的四条绑定规则 1.默认 ...

  10. RevitAPI 隐藏UI读取Revit文件

    1.1. 新建一个控制台项目 1.2. 添加Revit API引用 我们找到revit安装目录下的这两个DLL添加到项目引用中 RevitNET.dll RevitAPI.dll 修改属性:复制本地: ...