Synchronized面试总结

Synchronized面试总结

1. 说说自己对于synchronized关键字的了解

  1. Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法
  2. Synchronized的作用主要有三个
    1. 原子性:确保线程互斥的访问同步代码
    2. 可见性:保证共享变量的修改能够及时可见
    3. 有序性:有效解决重排序问题
  3. Synchronized总共有三种用法
    1. 当synchronized作用在实例方法时,监视器锁(monitor)便是对象实例(this)
    2. 当synchronized作用在静态方法时,监视器锁(monitor)便是对象的Class实例,因为Class数据存在于永久代,因此静态方法锁相当于该类的一个全局锁
    3. 当synchronized作用在某一个对象实例时,监视器锁(monitor)便是某个对象实例
  4. synchronized 内置锁 是一种 对象锁作用粒度是对象 ,是 可重入 的。其可重入最大的作用是避免死锁(子类同步方法调用了父类同步方法,如没有可重入的特性,则会发生死锁;)

2. synchronized关键字的底层原理?

  1. 任何一个对象都有一个Monitor与之关联,当对象的Monitor被持有后,该对象处于被锁定状态
  2. 当我们进⼊⼀个⽅法的时候,执⾏monitorenter,就会获取当前对象的⼀个所有权,这个时候monitor进⼊数为1,当前的这个线程就是这个monitor的owner
  3. 如果你已经是这个monitor的owner了,你再次进⼊,就会把进⼊数+1
  4. 当执⾏完monitorexit,对应的进⼊数就-1,直到为0,才可以被其他线程持有
  5. 所有的互斥,其实在这⾥,就是看你能否获得monitor的所有权,⼀旦你成为owner,就是获得锁者

3. Monitor底层原理

监视器可以确保监视器上的数据在同一时刻只会有一个线程在访问。

  1. Monitor是由ObjectMonitor实现的
  2. ObjectMonitor中有两个队列,_WaitSet 和 _EntryList
  3. 当多个线程同时访问一段同步代码时:首先会进入 _EntryList 集合,当线程获取到对象的monitor后,进入 _Owner区域并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1
  4. 若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入WaitSet集合中等待被唤醒;
  5. 若当前线程执行完毕,也将释放monitor(锁)并复位count的值,以便其他线程进入获取monitor(锁);

4. JDK1.6之后对synchronized关键字进行的优化?

JDK1.6版本为了弥补Synchronized的性能缺陷,设计了Synchronized锁的膨胀升级

  1. 无锁状态:当对象锁被创建出来时,在线程获得该对象锁之前,对象处于无锁状态。
  2. 偏向锁:在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,因此为了减少同一线程获取锁(会涉及到一些CAS操作,耗时)的代价而引入偏向锁。
  3. 轻量级锁:对于锁竞争比较激烈的场合,偏向锁就失效了,因为这样场合极有可能每次申请锁的线程都是不相同的,就升级为轻量级锁。
  4. 重量级锁:轻量级锁时,前对象锁被其他线程持有,于是该线程进行自旋,如果自旋失败到达阈值(默认是10),则将升级为重量级锁.

在这里插入图片描述

锁的膨胀升级,只能升不能降,也就是说升级过程不可逆

5. 对象被创建的过程

在这里插入图片描述

6. Java对象头的组成

  • Mark Word(见下图):无锁状态下,Java对象头里的Mark Word里默认存储对象的HashCode、分代年龄和锁标记位。在64位的JVM中,Mark Word为64 bit。
    在这里插入图片描述

  • Class Metadata Address:存储到对象类型数据的指针。

  • Array length:数组的长度(如果当前对象是数组)

Java对象头又存在于Java堆中,堆内存分为三部分:对象头,实例数据和对齐填充。

7. synchronized关键字与ReentrantLock的区别

  1. 都是可重入锁:自己可以再次获取自己的内部锁,同一线程每次获取锁,计数器加一,释放锁,计数器减一,计数为0,代表完全释放该锁
  2. synchronized依赖于JVM实现,ReentrantLock依赖于API
  3. 相比synchronized,ReentrantLock增加了一些高级功能
    1. 等待可中断 : ReentrantLock提供了一种能够中断等待锁的线程的机制,通过 lock.lockInterruptibly() 来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。
    2. 可实现公平锁 : ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。ReentrantLock默认情况是非公平的,可以通过 ReentrantLock类的ReentrantLock(boolean fair)构造方法来制定是否是公平的。
    3. 可实现选择性通知(锁可以绑定多个条件): synchronized关键字与wait()和notify()/notifyAll()方法相结合可以实现等待/通知机制。ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition()方法。
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值