一、概念
Java的ReentrantLock叫可重入锁,这意味着同一个线程可以多次获取同一个锁而不会产生死锁。
在ReentrantLock中,同一个线程如果已经获得了锁,再次尝试获得锁时会成功,并且会增加一个内部计数器,这就是可重入的概念。
可重入锁的一个好处是:可以避免死锁,因为一个线程如果已经持有了锁,则它可以再次获取这个锁而不会被自己阻塞。
但是,不同线程是不可以多次获取同一个未释放的锁。
二、示例代码
@ApiScan
@Controller
@Slf4j
public class TestController {
private final ReentrantLock lock = new ReentrantLock();
@RequestMapping(value="/test", method = RequestMethod.GET)
@ResponseBody
public void doTwiceLock(){
lock.lock();
try{
System.out.println("hello 1");
lock.lock();
try{
System.out.println("hello 2");
}finally {
lock.unlock();
}
}finally {
lock.unlock();
}
}
}
请求这个接口,会发现调用成功。
将上面的代码微调下:
@ApiScan
@Controller
@Slf4j
public class TestController {
private final ReentrantLock lock = new ReentrantLock();
@RequestMapping(value="/test", method = RequestMethod.GET)
@ResponseBody
public void doTwiceLock(){
lock.lock();
try{
System.out.println("hello 1");
lock.lock();
try{
System.out.println("hello 2");
}finally {
lock.unlock();
}
}finally {
}
}
}
此时第一次调用时是成功的,但是第二次调用失败!
因为第一次调用之后,lock了两次,但是只有一次unlock,此时锁还没处于释放状态。