什么是重入锁?
好了,现在大家知道我们为什么要使用锁了。那什么是重入锁呢。通常情况下,锁可以用来控制多线程的访问行为。那对于同一个线程,如果连续两次对同一把锁进行lock,会怎么样了?对于一般的锁来说,这个线程就会被永远卡死在那边,比如:
- void handle() {
- lock();
- lock(); //和上一个lock()操作同一个锁对象,那么这里就永远等待了
- unlock();
- unlock();
- }
这个特性相当不好用,因为在实际的开发过程中,函数之间的调用关系可能错综复杂,一个不小心就可能在多个不同的函数中,反复调用lock(),这样的话,线程就自己和自己卡死了。
所以,对于希望傻瓜式编程的我们来说,重入锁就是用来解决这个问题的。重入锁使得同一个线程可以对同一把锁,在不释放的前提下,反复加锁,而不会导致线程卡死。因此,如果我们使用的是重入锁,那么上述代码就 可以正常工作。你唯一需要保证的,就是unlock()的次数和lock()一样多。这样是不是方便很多呢?
重入锁提供的最重要的方法就是lock()
- void lock():加锁,如果锁已经被别人占用了,就无限等待。
这个lock()方法,提供了锁最基本的功能,拿到锁就返回,拿不到就等待。因此,大规模得在复杂场景中使用,是有可能因此死锁的。因此,使用这个方法得非常小心。
如果要预防可能发生的死锁,可以尝试使用下面这个方法:
- boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException:尝试获取锁,等待timeout时间。同时,可以响应中断。
这是一个比单纯lock()更具有工程价值的方法,如果大家阅读过JDK的一些内部代码,就不难发现,tryLock()在JDK内部被大量的使用。