此系列文章是参考《JAVA并发编程从入门到精通》一书写的一些读后笔记,其中也会进行扩展补充,写的不准确的地方还望广大同胞指出,大家一起学习,一起码奴。
Lock的使用方式
Lock是一个接口,提供了无条件的、可轮询的、定时的、可中断的锁获取操作,其加锁和解锁方式都是显式的。ReentrantLock是Lock的实现类,许多线程都竞争相同锁定时,使用ReentrantLock的吞吐量通常比synchronized高,下面来看下基本用法:
public static ReentrantLock reentrantLock = new ReentrantLock();
public static void testReentrantLock(){
try {
reentrantLock.lock();
//业务逻辑
Thread.sleep(100l);
System.out.println(Thread.currentThread().getName());
} catch (Exception ex) {
} finally {
reentrantLock.unlock();
}
}
如上,reentrantLock.lock()方法代表加锁, reentrantLock.unlock()表示解锁。我在一个类中声明了静态变量ReentrantLock以及静态方法testReentrantLock(),这样在调用testReentrantLock()时,lock与unlock之间的代码片段就是会受到锁的保护。这样也说明了reentrantLock与synchronized之间的区别
reentrantLock与synchronized的区别
Lock必须手动释放和开启锁,而synchronized不需要我们手动释放或者开启锁
Lock只适用于代码块锁,synchronized的使用方式更多一些
synchronized是,Lock有多个锁获取的方式
synchronized | Lock | |
---|---|---|
存在层次 | Java的关键字,在jvm层面上 | 是一个类 |
锁的释放 | 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 | 在finally中必须释放锁,不然容易造成线程死锁 |
锁的获取 | 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 | 分情况而定,Lock有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待 |
锁状态 | 无法判断 | 可以判断 |
锁类型 | 可重入 不可中断 非公平 | 可重入 可判断 可公平(两者皆可) |
性能 | 少量同步 | 大量同步 |