Java面试系列之并发编程专题-Synchronized灵魂拷问

金三银四跳槽季即将来临,想必有些猿友已经蠢蠢欲动在做相关的准备了!在接下来的日子里,笔者将坚持写作、分享Java工程师在面试求职期间的方方面面,包括简历制作、面试场景复现、面试题解答、谈薪技巧 以及 项目的实战!今天我们先拿Java里面的并发编程之Synchronized来开刀!

以下内容来自 程序员实战基地 fightjava.com 一位网友最近的面试场景,笔者尝试着将其复现,话不多说,咱们直接开撸!

1. 面试官:Synchronized有用过吗?谈谈你对它的理解

(1)画外音:面试官主要是想了解你有没有Java并发编程方面的经验,可以讲讲它的概念和部分原理!

(2)回答Synchronized是Java的关键词,JVM实现的一种可以实现并发产生的多个线程互斥同步访问共享资源的 方式,也可以说是一种 “同步互斥锁”,在实际代码中可用于修饰代码块、方法、静态方法以及类;适用于单体应用系统架构

2.面试官:嗯,说一说它的原理?

(1)画外音:这么快就问原理,看来是动真格的了,不是随便问问而已!

(2)回答 通过查看被Synchronized 修饰过的代码块编译后的字节码,会发现编译器会在 被Synchronized修饰过的代码块 的前、后生成两个字节码指令:monitorenter、monitorexit;

这两个字节码指令的含义:当JVM执行到monitorenter指令时,首先会尝试着先获取对象(共享资源)的锁,如果该对象没有被锁定、又或者当前线程已经拥有了这个对象的锁时,则锁的计数器count加1,即执行 +1 操作;当JVM执行monitorexit指令时,则将锁的计数器count减一,即执行 -1 操作;

当计数器count为0时 ,该对象的锁就被释放了!!

如果当前线程获取该对象的锁失败了,则进入堵塞等待状态,直到该对象的锁被另外一个线程释放为止;即Java中的Synchronize底层其实是通过对象(共享资源)头、尾设置标记,从而实现锁的获取和释放。

3.面试官:你刚才提到获取对象的锁,说一说“锁”到底是什么,如何确定对象的锁?

(1)画外音:这是笔者自行想象、扩充的内容!

(2)回答“锁” 可以理解为monitorenter和monitorexit字节码指令之间的一个 Reference类型的参数,即要锁定Lock和解锁UnLock的对象

众所周知,使用Synchronized可以修饰不同的对象,因此,对应的对象的锁可以这么确定:

A.如果Synchronized 明确指定了“锁”的对象,比如Synchronized变量、 Synchronized(this) 等,说明加、解锁的即为该变量、当前对象;

B.若 Synchronized 修饰的方法为非静态方法,表示此方法对应的对象为“锁”对象; 若 Synchronized 修饰的方法为静态方法,则表示此方法对应的类对象为“锁”对象;

注意:当一个对象被锁住时,对象里面所有用Synchronized 修饰的方法都将产生堵塞, 而对象里非Synchronized 修饰的方法可正常被调用,不受锁的影响;

4.面试官:什么叫可重入锁,为什么说Synchronized是可重入锁?

(1)画外音:这面试官脑袋瓜转得可真快!

(2)回答通俗地讲,“可重入”指的是:当 当前线程获取到了当前对象的锁之后,如果后续的操作仍然需要获取获取该对象的锁时,可以不用再次重新获取,即可以直接操作该对象(共享资源);

可重入性是锁的一个基本要求,是为了解决自己锁死自己的情况,比如一个类的同步方法调用另一个同步方法时,假如Synchronized不支持重入,进入method2方法时当前线程已经获得锁,而在method2方法里面执行method1时当前线程又要去尝试获取锁,这时如果不支持重入,它就要等待释放,把自己阻塞,导致很有可能自己锁死自己!

对Synchronized来说,可重入性是显而易见的,刚才提到,在执行monitorenter指令时,如果这个对象没有锁定,或者当前线程已经拥有了这个对象的锁,就把锁的计数器+1,其实本质上就是通过这种方式实现了可重入性(而不是已拥有了锁则不能继续获取)。

5.面试官:说一说JVM底层对Java的原生锁做了哪些优化?

(1)画外音:这有点难,特意上网参考了下,原来是关于锁竞争和升级的……

(2)回答在Java 6以前前,Monitor的实现完全依赖底层操作系统的互斥锁来实现,也就是上面在问题2中所阐述的获取、释放锁的逻辑;由于Java的线程与操作系统的原生线程有映射关系,如果要将一个线程进行阻塞或唤起 都需要操作系统的协助,这就需要从用户态切换到内核态来执行,这种切换代价十分昂贵,很耗处理器时间,现代JDK中做了大量的优化;

更多请见:http://www.mark-to-win.com/tutorial/51077.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值