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. python基础-列表List及内置方法

    数据类型之列表-List 用途:用于存一个或多个不同类型的值 定义:通过中括号存值,每个值之间通过逗号进行分隔 l1 = [1,'a',3,'b'] 特性:有序.可变.存多个值的数据类型 常用方法: ...

  2. Python基础知识-运算符

    今日学习内容 用户交互 用户交互就是人向机器发出指令,机器分析处理后,给人们返回操作结果(装13的说法).直白地讲,就是人往计算机中输入(input)数据,计算机输出(output)结果.交互的本质就 ...

  3. 命运Ⅰ&命运Ⅱ

    upd:为啥下面的相关博文都是各种退役记(这TM怎么就相关了) 竟然被卡线了,16名,我这几次考试也是炸到了一定境界了... 前三次模拟总榜rk1,第一次分机房rk4,第二次分机房rk11,第三次分机 ...

  4. Python实现发送邮件代码

    代码如下: # -*- coding: utf-8 -*- #!/usr/bin/env python # @Time : 2017/12/22 17:50 # @Desc : # @File : m ...

  5. 开源 ERP 系统 GoodERP

    如果你有一个苹果,我也有一个苹果,彼此交换后,你我还是一人一个苹果,但是如果你有一个想法,我有一个想法,彼此交换后,你我就都有两个想法,三个人呢?一百个人呢? 使用openobject框架 重写全部功 ...

  6. linux日志查找方法

    grep "xxxx" *201812* | grep "xxx" | awk -F, '{if(substr($1,1,10)=="2018-12- ...

  7. SSM整合相关试题

    1.下列关于Spring自动装配的说法中,错误的是() A 在Spring配置文件中,可以通过<bean>元素的autowire属性指定自动装配方式 B autowire属性值可以设置为n ...

  8. Md5实例

    MD5实例 我的md5源码 当我们对数据进行操作时,存储到数据库时,有时候不希望别人能够看到,通过md5能够实现对数据的加密. java代码 ```javaimport org.springframe ...

  9. [springboot 开发单体web shop] 6. 商品分类和轮播广告展示

    商品分类&轮播广告 因最近又被困在了OSGI技术POC,更新进度有点慢,希望大家不要怪罪哦. 上节 我们实现了登录之后前端的展示,如: 接着,我们来实现左侧分类栏目的功能. ## 商品分类|P ...

  10. hdu 1233 (prim,最小生成树) 还是畅通工程

    还是畅通工程Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...