【Java多线程】synchronized和ReentrantLock的区别

可重入性:

  首先说明可重入锁的概念,即一个线程尝试去获取自己已经持有的锁,可以成功获取,而其他线程不可以获取。这样做的优点简而言之是——递归无阻塞的同步机制。若锁不是可重入的,在子类的同步方法中调用父类的同步方法,会无法第二次获取子对象的锁,导致死锁。
  从名字上理解,ReentrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也是可重入的,两者关于这个的区别不大。两者都是同一个线程没进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。

锁的实现:

  synchronized是依赖于JVM实现的,而ReentrantLock是JDK实现的,有什么区别,说白了就类似于操作系统来控制实现和用户自己敲代码实现的区别。前者的实现是比较难见到的,后者有直接的源码可供阅读。

性能的区别:

  在synchronized优化以前,synchronized的性能是比ReentrantLock差很多的,但是自从synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized,其实synchronized的优化我感觉就借鉴了ReentrantLock中的CAS技术。都是试图在用户态就把加锁问题解决,避免进入内核态的线程阻塞。

功能的区别:

  便利性:synchronized的使用比较方便简洁,并且由编译器去保证锁的加锁和释放,而ReentrantLock需要手动来加锁和释放锁,为了避免代码异常没有执行unlock()方法而造成死锁,开发中必须在finally中声明释放锁。

  锁的细粒度和灵活度:很明显是ReentrantLock优于synchronized

ReentrantLock独有的能力:

  1.  ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。
    
  2.  ReentrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。
    
  3.  ReentrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。
    

ReentrantLock实现的原理:
  简单来说,ReentrantLock的实现是一种自旋锁,通过循环调用CAS操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。想尽办法避免线程进入内核的阻塞状态是我们去分析和理解锁设计的关键钥匙。

ReentrantLock的使用场景:
  当你需要使用ReentrantLock的三个独有功能时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中的`synchronized`和`ReentrantLock`都是用来实现线程同步的机制,它们的作用是让多个线程按照一定的顺序执行,避免出现竞态条件(race condition)。 下面是`synchronized`和`ReentrantLock`的区别: 1. 语法:`synchronized`是Java语言内置的关键字,`ReentrantLock`是Java提供的一个类。 2. 锁的获取方式:`synchronized`是隐式获取锁,当线程进入同步块或同步方法时会自动获取锁并在执行完毕后释放锁;`ReentrantLock`则需要显式获取和释放锁,即在代码中通过调用`lock()`方法获取锁,在执行完毕后再通过调用`unlock()`方法释放锁。 3. 锁的可重入性:`synchronized`是可重入的,即同一个线程在已经获取到锁的情况下,可以重复获取该锁而不会发生死锁;`ReentrantLock`也是可重入的,但需要注意的是,每次获取锁都会增加锁的计数器,需要在释放锁时把计数器减一,否则将导致其他线程无法获取到锁。 4. 锁的可中断性:`synchronized`是不可中断的,即当一个线程获取到锁之后,其他线程只能等待锁被释放;`ReentrantLock`可以通过调用`lockInterruptibly()`方法实现可中断锁,即当其他线程在等待锁的时候,可以通过调用该方法中断当前线程的等待。 5. 条件变量:`ReentrantLock`提供了`Condition`接口来实现线程之间的协调与通信,而`synchronized`则没有。 总的来说,`ReentrantLock`比`synchronized`更加灵活和可控,但需要注意的是,使用`ReentrantLock`时需要手动管理锁的获取和释放,否则容易导致死锁;而`synchronized`则可以简化代码,但对于一些复杂的同步场景可能会有限制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值