Synchronized与J.U.C(java.util.concurrent)下的ReetrantLock区别及使用场景

通常在面试时,面试官会问到你,Java中实现同步有哪些方式(或者可以问你Java中有哪些加锁的方式?或是Java中有哪些方式可以保证线程并发安全?)此类的问题,今天谈谈相应的实现方式和使用场景。

Synchronized关键字

这个JVM原生语法层面的互斥锁,核心是通过使用对象锁进行实现(对象锁,简单的说在每个Java对象的对象头中的Mark Word中都会有一个Monitor对象-由C语言的ObjectMonitor实现),

  1. 在对实例方法或者类方法(static方法)添加此关键字时,是通过标志位ACC_SYNCHRONIZED标志此方法为同步方法(本质跟锁代码块一样通过Monitor对象的两个指令实现)。相应的如果是实例方法,即没有指定要进行锁定的对象,那么就使用当前的实例对象来走位锁对象,而如果是类方法,则使用当前类的Class对象作为锁对象。
  2. 在对代码块添加此关键字时,是通过字节码指令monitorenter,monitorexit实现(源码在ObjectMonitor中),当执行monitorenter命令时,首先要尝试获取对象的锁,如果这个对象没有被锁定,或者当前线程已经拥有那个对象的锁(ObjectMonitor->_owner),把锁的计数器(ObjectMonitor->_recursive)加1,相应的执行monitorexit时进行减1,当计数器为0时,对象锁被释放,(这里也是可重入锁的实现原理,保证线程不被自己锁死)。如果获取失败,就当前线程就阻塞等待,直到对象锁被另一个线程释放为止。
最后,你应该要知道,Java线程都是映射到OS的原生线程上的,要阻塞或者唤醒一个线程,都需要叫操作系统来帮忙,
(使real墙钟时间远大于user+sys的CPU耗时)
这就需要由 用户态->内核态 的转换,这种状态的转换是需要耗费很多处理器时间的。所以Synchronized是一个
重量级(Heavyweight)的操作,应该在确实有必要时才使用这种操作。当前在虚拟机中本身也会进行一些优化
(JDK1.6中),
例如:偏向锁,轻量级的自旋锁(默认10次),类似的操作来避免频繁切入内核态中。

J.U.C->ReetrantLock

在基本用法上,ReetrantLock与Synchronized很相似,都具体线程重入的特性,但是在代码的写法上就有一定的区别了,ReentrantLock表现为API层面的互斥锁(通过lock(),unlock()方法配合try/finally块来完成,面试中请记得ReentrantLock的原理为Java中的AQS(抽象队列同步器),具体为两个双向列表+volatile的标志位state+CAS和自旋操作)。
相比Synchronized,ReentrantLock增加了一些高级功能,主要是等待可中断,可实现公平锁(两种所默认都是非公平锁(每次都是所有线程一起竞争资源,不排队,为了提高吞吐量)),以及锁可以绑定多个条件。

  1. 等待可中断指当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,去处理其他的事情,可中断特性对处理执行时间非常长的同步块很有帮助。
  2. 公平锁的指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获取锁:而非公平锁则不保证这一点,在锁被释放时,任何一个等待的线程都有机会获取取。可通过带boolean值的构造方法来使用公平锁。
  3. 锁绑定多个条件指的是一个ReentrantLock对象可以同时绑定多个Condition对象(AQS中),而Synchronized中,锁对象的wait(), notify()和notifyAll()方法可以实现一个隐含的条件,如果要多余一个的条件关联的时候,就必须得额外添加一个锁。ReentrantLock只需要多次调用newCondition()方法来获取多个Condition实例(构建多个ConditionQueue)即可。

所以如需使用上述功能的场景,ReentrantLock对象是一个很好的选择。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pHscccr_Ayyx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值