重入锁(ReentrantLock)

作者: 进击de小黑 | 来源:发表于2018-11-21 11:24 被阅读4次

    ReentrantLock

    重入锁使用java.util.concurrent.locks.ReentrantLock类来实现。它的几个重要方法如下:

    lock():获得锁,如果锁已经被占用,则等待。
    lockInterruptibly():获得锁,但优先响应中断。 
    tryLock():尝试获得锁,如果成功,返回true,失败返回false。该方法不等待,立即返回。
    tryLock(long time, TimeUnit unit):在给定时间内尝试获得锁。 unLock():释放锁。
    

    对于重入锁,同一个线程可以多次获得锁,但是释放锁的时候,也必须释放相同次数。否则会产生异常。

    Condition条件

    通过Condition的newCondition()方法可以生成一个与当前重入锁绑定的Condition实例。利用Condition对象,我们就可以让线程在合适的时间等待,或者在某一个特定的时间得到通知,继续执行。

    await() 方法会是当前线程等待,同时释放当前锁,当其他线程中使用signal() 或signalAll() 方法时,线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待;signal() 方法用于唤醒一个在等待中的线程。

    当线程使用Condition.await时,要求线程持有相关的重入锁,在Condition.await调用后,这个线程会释放这把锁。同理,在Condition.signal方法调用时,也要求线程先获得相关的锁。在signal方法调用后,系统会从当前Condition对象的等待队列中,唤醒一个线程。一旦线程被唤醒,它会重新尝试获得与之绑定的重入锁,一旦成功获取,就可以继续执行了。因此,在signal方法调用之后,一般需要释放相关的锁,谦让给被唤醒的线程,让他可以继续执行。

        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        public void method1(){
            try {
                lock.lock();
                //释放锁,类似于 Object wait,阻塞于此
                condition.await();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void method2(){
            try {
                lock.lock();
                 //不释放锁类,似于Object notify
                condition.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
    

    相关文章

      网友评论

        本文标题:重入锁(ReentrantLock)

        本文链接:https://www.haomeiwen.com/subject/lyvqqqtx.html