JAVA并发-锁介绍1-ReentrantLock可重入锁
目录
在Java并发编程中经常会用到各种类型的锁,比如乐观锁、悲观锁、自旋锁、可重入锁、轮询锁、定时锁、读写锁等,锁是解决并发冲突的重要工具。本文对ReentrantLock可重入锁进行重点介绍,其余锁类型后续将在其他文章中分别介绍。
ReentrantLock可重入锁定义
可重入锁指的是 可重复可递归调用 的锁,ReentrantLock是JAVA SE 5.0时引入的互斥锁,由java.util.concurrent框架提供。
ReentrantLock支持公平锁和非公平锁
ReentrantLock实现了lock接口,有两个构造方法,一个是无参的 ReentrantLock() ,另一个带布尔类型参数public ReentrantLock(boolean fair)。其中 fair为true实现公平锁,无参或者fair为false实现非公平锁。
公平锁与非公平锁的区别主要在线程获取锁的规则,公平锁是按照线程加锁的顺序,即等待时间最长的线程将优先获得锁,符合FIFO(先进先出)的规则;非公平锁则是线程随机获得锁。公平锁能避免线程饥饿,非公平锁性能更好。其中线程饥饿指的是线程一直无法获得其所需的资源而导致其任务一直无法进展的一种活性故障。
ReentrantLock线程等待简单示例
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockSample {
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
public static void main(String args[]) throws InterruptedException{
lock.lock();
System.out.println("Main Thread Begin");
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
lock.lock();
condition.signal();
System.out.println("Sub Thread Run");
lock.unlock();
}
}).start();
condition.await();
lock.unlock();
System.out.println("Main Thread End");
}
}
示例主要介绍了通过Condition接口实现线程间的等待通知机制,其中使用Conditon接口前,需要通过lock()方法获得锁,然后调用Condition接口的await方法使得当前线程进入等待状态,并等待其他线程调用Condition接口的signal方法唤醒该线程。
ReentrantLock响应中断方式与限时等待
ReentrantLock支持 响应中断 方式获取锁,即调用ReentrantLock的 lockInterruptibly 方法进行获取,必要时可以通过调用进程的interrupt()方法中断等待,抛出InterruptedException异常。
ReentrantLock也支持 限时等待 获取锁,通过调用ReentrantLock的 trylock 方法进行获取,trylock不带参数表明立即返回获取锁的结果,带参数则表示在指定时间间隔获取锁,获取成功返回true,失败返回false。
ReentrantLock中Lock与TryLock的区别
Lock.lock()始终等待不能被interrupt打断;
Lock.lockInterruptibly()进行等待,但可能被interrupt中断等待;
Lock.trylock()不会等待,直接返回获取锁的结果;
Lock.tryLock(long time, TimeUnit unit)在指定时间内可被interrupt打断,如果指定时间内获取到锁返回true,超过指定时间否则返回false。
Lock和Synchronized的区别
类型:Lock是接口,Synchronized是关键字。
范围:Lock作用于代码块,Synchronized作用于类、方法、代码块。
中断:Lock可以让等待锁的线程响应式中断,Synchronized的会一直等待下去。
释放:Lock需要手动释放锁,Synchronized会自动释放锁。
效率:Lock相对可以Synchronized提高读的效率。
公平与非公平锁:Lock实现可重入、可中断、公平或非公平锁,Synchronized实现可重入、不可中断、非公平锁。
线程有无拿到锁:Lock可以知道线程有没拿到锁,Synchronized则不行。