一、简介
在之前的线程系列文章中,我们介绍到了使用synchronized
关键字可以实现线程同步安全的效果,以及采用wait()
、notify()
和notifyAll()
方法,可以实现多个线程之间的通信协调,基本可以满足并发编程的需求。
但是采用synchronized
进行加锁,这种锁一般都比较重,里面的实现机制也非常复杂,同时获取锁时必须一直等待,没有额外的尝试机制,如果编程不当,可能就容易发生死锁现象。
从 JDK 1.5 开始,引入了一个高级的处理并发的java.util.concurrent
包,它提供了大量更高级的并发功能,能大大的简化多线程程序的编写。
比如我们今天要介绍的java.util.concurrent.locks
包提供的ReentrantLock
类,一个可重入的互斥锁,它具有与使用synchronized
加锁一样的特性,并且功能更加强大。
下面我们一起来学习一下ReentrantLock
类的基本使用。
二、ReentrantLock 基本用法
在介绍ReentrantLock
之前,我们先来看一下传统的使用synchronized
对方法进行加锁的示例。
public class Counter {
private int count;
public void add() {
synchronized(this) {
count ++;
System.out.println("ThreadName:" + Thread.currentThread().getName() + ", count:" + getCount());
}
}
public int getCount() {
return count;
}
}
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
// 创建5个线程,同时对count进行加一操作
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
counter.add();
}
}).start();
}
// 假设休眠1秒,5个线程执行完毕
Thread.sleep(1000);
System.out.println("count:" + counter.getCount());
}
输出结果如下:
ThreadName:Thread-0, count:1
ThreadName:Thread-1, count:2
ThreadName:Thread-2, count:3
ThreadName:Thread-3, count:4
ThreadName:Thread-4, count:5
count:5
如果用ReentrantLock
替代,只需要将Counter
中的代码改造为如下:
public class Counter {
private final Lock lock = new ReentrantLock();
private int count;
public void add() {
// 加锁
lock