浅谈ReentrantLock和synchronized具体不一样

前言

软件并发已经成为现代软件开发的基础能力,而 Java 精心设计的高效并发机制,正是构建大规模应用的基础之一,掌握java并发编程已经成为日常开发中不可或缺的一部分。因此我会尝试谈一谈并发中的锁。

关键字

再入锁(重入锁),锁膨胀、降级;理解偏斜锁、自旋锁、轻量级锁、重量级锁,原子性,可见性,有序性

一、定义

ReentrantLock(再入锁,重入锁)

一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。再入锁通过代码直接调用 lock() 方法获取,代码书写也更加灵活。

synchronized(同步)

ynchronized 是 Java 内建的同步机制,所以也有人称其为 Intrinsic Locking,它提供了互斥的语义和可见性,当一个线程已经获取当前锁时,其他试图获取的线程只能等待或者阻塞在那里。
在 Java 5 以前,synchronized 是仅有的同步手段,在代码中, synchronized 可以用来修饰方法,也可以使用在特定的代码块儿上,本质上 synchronized 方法等同于把方法全部语句用 synchronized 块包起来。

二、对比

序号\机制 同步 (synchronized) 重入锁(ReentrantLock)
1 不支持公平性的控制 支持对锁的公平性(fairness)控制
2 可以被长期或一直阻塞 锁定期间, 是可以被其他线程打断的 (interrupt)
3 Condition 的构造方法newCondition
4 获取所有等待锁线程的List 的方法
5 lock();unlock();

三、使用及场景

1

当您使用同步块或方法时,您只需要编写 synchronized 关键字(并提供关联的对象),即可隐式地完成获取和释放锁的操作。
使用ReentrantLock,用户可以使用lock()和unlock()方法来获取和释放锁。
在Java中使用RentrantLock的规定方法是使用try-finally块。 调用锁后应立即使用try块,并应在finally块中释放锁。 这样,即使关键部分代码中抛出异常,也将释放锁定。

lock.lock();
try {    
  //…method body    
}finally {
  lock.unlock();
}
 

然而Synchronized,就没有强制性,因为隐式完成了获取和释放。

Synchronized(myObj){
 …
 …
}

因此,使用Synchronized编写的代码更加清晰易读。

2

Synchronized关键字强制所有锁的获取和释放以块结构的方式发生,这意味着当获取多个锁时,它们必须以相反的顺序释放,并且所有锁必须在与获取它们相同的词法范围内释放。

ReentrantLock提供了更大的灵活性,它允许在不同的作用域中获取和释放锁,并允许以任意顺序获取和释放多个锁。

使用ReentrantLock,可以使用以下代码,但不能同步。

private ReentrantLock lock;
public void methodA() {
 
  lock.lock();
 
}

public void methodB() {
 
  lock.unlock();
 
}

总结

1 分析好业务场景高竞争就用ReentrantLock,低竞争就用synchronized;

猜你喜欢

转载自blog.csdn.net/aa327056812/article/details/109658017