在java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可以抛弃synchronized关键字了。
在这些锁实现之前,如果我们想实现锁的功能,只能通过synchronized关键字,例子如下:
private static volatile int value;
public static void main() {
Runnable run = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
increaseBySync();
}
}
};
Thread t1 = new Thread(run);
Thread t2 = new Thread(run);
t1.start();
t2.start();
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(value);
}
private static synchronized int increaseBySync() {
return value++;
}
有了ReentrantLock之后,我们可以这样写:
private static volatile int value;
private static Lock lock = new ReentrantLock();
public static void main(String[] args) {
testIncreaseWithLock();
}
public static void main() {
Runnable run = new Runnable() {
@Override
public void run() {
try {
lock.lock();
for (int i = 0; i < 1000; i++) {
value++;
}
} finally {
lock.unlock();
}
}
};
Thread t1 = new Thread(run);
Thread t2 = new Thread(run);
t1.start();
t2.start();
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(value);
}
以上两段代码都可以实现value值同步自增1,并且value都能得到正确的值2000。下面我们就来分析下ReentrantLock有哪些功能以及它底层的原理。
可重入锁
从名字我们就可以看出ReentrantLock是可重入锁。可重入锁是指当某个线程已经获得了该锁时,再次调用lock()方法可以再次立即获得该锁。