Synchroninzed、Volatile、ReentrantLock、Atomic

Java中存在两种锁机制,Lock和Synchronized。

首先说说这两种锁机制之间的区别:

相同点:

1、ReentrantLock(可重入互斥锁),它具有与synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但是其功能更加强大。

2、从底层数据结构来看,synchronized底层是基于CAS操作的等候队列,而ReentrantLock底层是基于AQS通过构造一个等候队列,且对该队列的操作是通过CAS操作。

不同点:

1、ReentrantLock多了锁投票、定时锁等候、中断锁等候,但是synchronized锁不能够被打断。

2、synchronized是在JVM层面上实现的,不但可以通过监控工具来监控synchronized的锁定,而且在代码执行出现异常的时候,JVM会自动释放锁定;Lock是通过代码来实现的,要保证锁定一定会被释放,就必须将unLock()放在finally{}中执行。

3、在资源竞争不是很激烈的情况下,synchronized的性能要优于ReentrantLock;但是在资源竞争很激烈的情况下,synchronized的性能会下降几十倍,但是ReentrantLock的性能可以维持常态。

4、Atomic:不激烈的情况下,性能比synchronized稍逊;但是在激烈的情况下,Atomic的性能要优于ReentrantLock一倍左右。但是Atomic存在一个缺点,就是只能够同步一个值,在一段代码中只能出现一个Atomic的变量。

线程A、B都要获取对象o的锁,假设线程A获取了对象o的锁,B将等待线程A释放对o的锁。

(1)如果使用synchronized,那么如果A不释放锁,B将一直等待下去,不能被中断。

(2)如果使用ReentrantLock,那么如果A不释放锁,B在等待足够长的时间之后,就会中断等待,而去干别的事情。

ReentrantLock获取锁定的三种方式:

1>Lock(),如果获取了锁,立即返回,如果别的线程持有锁,当前线程一直处于休眠状态,直到获取锁。

2>tryLock(),如果获取了锁,立即返回true,如果有别的线程持有锁,返回false。

3>tryLock(long timeout,TimeUnit unit),如果获取了锁,立即返回true,如果别的线程持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁,则返回到true,如果等待超时,则返回false。

4>lockInterruptibly(),如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断。

volatile和synchronized之间的区别:

1、volatile本质是在告诉JVM当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞。

2、volatile只能使用在变量级别;synchronized则可以使用在变量、方法和类级别的。

3、volatile仅能实现变量的修改可见性,不能保证原子性;synchronized则可以保证变量的可修改性和原子性。

4、volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。

5、volatile标记的变量不会被编译器优化;synchronized标记的变量可以被优化。

什么时候用ReentrantLock代替synchronized?

在确实需要一些synchronized所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁或者轮询锁我们可以使用ReentrantLock。在一般情况下,使用synchronized即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值