ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

synchronized和ReentrantLock

synchronized和ReentrantLock

ReentrantLock

可重入互斥锁,和synchronized的定位类似,都用于实现互斥效果,保证线程安全。

ReentrantLock的用法:

  • lock():加锁,获取不到锁就死等
  • trylock():超时时间加锁
    如果设置了超时参数,超时后放弃加锁
    如果不设置超时参数,不会导致阻塞,加锁成功返回true,失败返回false
  • unlock():解锁
ReentrantLock lock = new ReentrantLock(); -------------------------------------------------- lock.lock(); try { //working } finally { lock.unlock(); }

ReentrantLock和synchronized的区别

  1. synchronized是一个关键字,是JVM内部实现的(大概率是基于C++实现)
    ReentrantLock是标准库的一个类,在JVM外实现的(基于Java实现)
  2. synchronized使用代码块进行加锁解锁,不需要考虑解锁问题
    ReentrantLock需要lock/unlock方法,使用灵活,但是容易遗漏unlock
  3. synchronized在申请锁失败后会死等
    ReentrantLock可以使用trylock方法等待一段时间后就放弃
  4. synchronized是非公平锁
    ReentrantLock默认是非公平锁,但是可以通过构造方法传入一个true开启公平锁模式
  5. synchronized使用Object类的wait/notify实现等待/唤醒,每次唤醒都是随机唤醒
    ReentrantLock可以搭配Condition类实现等待/唤醒,可以更精准得唤醒某个指定的线程。
  • 竞争不激烈的时候使用synchronized锁,效率更高,自行解锁更方便
  • 锁竞争激烈的时候使用ReentrantLock锁,搭配trylock方法更灵活得控制加锁,而不是死等
  • 如果要使用公平锁,使用ReentrantLock锁
返回列表