从Java 5开始,引入了一个高级的处理并发的java.util.concurrent包,它提供了大量更高级的并发功能,能大大简化多线程程序的编写。
我们知道Java语言直接提供了synchronized关键字用于加锁,但这种锁一是很重,二是获取时必须一直等待,没有额外的尝试机制。
java.util.concurrent.locks包提供的ReentrantLock用于替代synchronized加锁,我们来看一下传统的synchronized代码:
public class Counter {
private int count; public void add(int n) { synchronized(this) {
count += n;
}
}
}如果用ReentrantLock替代,可以把代码改造为:
public class Counter {
private final Lock lock = new ReentrantLock(); private int count; public void add(int n) {
lock.lock(); try {
count += n;
} finally {
lock.unlock();
}
}
}因为synchronized是Java语言层面提供的语法,所以我们不需要考虑异常,而ReentrantLock是Java代码实现的锁,我们就必须先获取锁,然后在finally中正确释放锁。
顾名思义,ReentrantLock是可重入锁,它和synchronized一样,一个线程可以多次获取同一个锁。
和synchronized不同的是,ReentrantLock可以尝试获取锁:
if (lock.tryLock(1, TimeUnit.SECONDS)) { try {
...
} finally {
lock.unlock();
}
}