synchronized与ReentrantLock的区别

synchronized 关键字的用法

  1. 修饰实例方法:synchronized修饰实例方法, 则用到的锁,默认为this当前方法调用对象;
  2. 修饰静态方法:synchronized修饰静态方法, 则其所用的锁,默认为Class对象;
  3. 修饰代码块:synchronized修饰代码块, 则其所用的锁,是某个指定Java对象;

synchronized修饰实例方法

  • 使用当前对象this充当锁,完成对当前方法的锁定,只有获取this锁的线程才能访问当前方法;
  • 并发过程中,同一时刻,可以有N个线程请求执行方法,但只有一个线程可以持有this锁,才能执行;
  • 不同线程,持有的对象,必须相同;
public class Foo{
    //实例方法
    public synchronized void dosth1(){
      //获取this锁,才能执行该方法
    }
    //实例方法
    public void dosth2(){
        synchronized(this){
          }
     }
 }

synchronized修饰静态方法

  • 使用当前对象的Class对象充当锁,完成对当前方法的锁定,只有获取Class锁的线程才能访问当前方法;
  • 不同线程,持有的对象,可以不同,但必须相同class类型
public class Foo{
    //实例方法
    public synchronized static void dosth1(){
      //获取this锁,才能执行该方法
    }
    //实例方法
    public static void dosth2(){
        synchronized(this){
          }
     }
 }

ReentrantLock

ReentrantLock实现了 Lock接口,Lock接口中定义了 lock()、 unlock()tryLock()等相关操作。

ReentrantLock总共有三个内部类:Sync、NonfairSync、FairSync。
NonfairSync 类继承了 Sync类,表示采用非公平策略获取锁:每一次都尝试获取锁,不会按照公平等待的原则进行等待,不会让等待时间最久的线程获得锁。
FairSync类也继承了 Sync类,表示采用公平策略获取锁:当资源空闲时,它总是会先判断 sync队列是否有等待时间更长的线程,如果存在,则将当前线程加入到等待队列的尾部,实现了公平获取原则。
ReentrantLock构造函数:默认是采用的非公平策略获取锁。

synchronized和reentrantlock都是Java中用于实现线程同步的机制,它们的主要区别如下:

锁的获取方式不同:synchronized是隐式锁,即在进入同步代码块或方法时自动获取锁,退出时自动释放锁;而reentrantlock是显式锁,需要手动获取和释放锁。

可重入性不同:synchronized是可重入锁,即同一个线程可以多次获取同一把锁,而reentrantlock也是可重入锁,但需要手动实现。

等待可中断性不同:synchronized不支持等待可中断,即线程无法响应中断请求,而reentrantlock支持等待可中断,可以响应中断请求。

公平性不同:synchronized是非公平锁,即无法保证等待时间最长的线程最先获取锁,而reentrantlock可以通过构造函数指定是否为公平锁。

性能不同:在低并发情况下,synchronized的性能优于reentrantlock,但在高并发情况下,reentrantlock的性能优于synchronized

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值