美文网首页
java锁机制之「ReentrantLock」

java锁机制之「ReentrantLock」

作者: 乌木山 | 来源:发表于2019-11-16 17:01 被阅读0次

    在前文中,我们已经提到过java中一个重要的同步关键字synchronized。今天我们来介绍另一个重要的锁机制:ReentrantLock。
    ReentrantLock提供了synchronized关键字一致的语义功能。但是提供了更丰富的使用场景。

    - ReentrantLock synchronized
    使用方式 需要显式的调用lock()unlock() jvm保证锁的自动释放
    等待 可中断,可设置超时 不支持
    公平性 提供了公平锁/非公平锁 非公平锁
    阻塞 tryLock()实现非阻塞获取锁 只有阻塞

    使用

    ReentrantLock需要手动的释放锁,否则会导致其他线程永远无法获取到锁,因此总是记得用try{}finally{}释放锁。

        public void m() {
          lock.lock();  // block until condition holds
          try {
            // ... method body
          } finally {
            lock.unlock()
          }
        }
    

    ReentrantLock同时提供了Condition条件变量,获取的方式是ReentrantLock.newCondition()
    每一个条件变量有自己单独的等待队列,在调用Condition的await()signal()方法时,必须先获取ReentrantLock的锁。
    如果说ReentrantLock是用来代替synchronized,那Condition则是用来代替Object的wait(),notify()的,使用方式如下:

       class BoundedBuffer {
         final Lock lock = new ReentrantLock();
         final Condition notFull  = lock.newCondition(); 
         final Condition notEmpty = lock.newCondition(); 
      
         final Object[] items = new Object[100];
         int putptr, takeptr, count;
      
         public void put(Object x) throws InterruptedException {
           lock.lock();
           try {
             while (count == items.length)
               notFull.await();
             items[putptr] = x;
             if (++putptr == items.length) putptr = 0;
             ++count;
             notEmpty.signal();
           } finally {
             lock.unlock();
           }
         }
      
         public Object take() throws InterruptedException {
           lock.lock();
           try {
             while (count == 0)
               notEmpty.await();
             Object x = items[takeptr];
             if (++takeptr == items.length) takeptr = 0;
             --count;
             notFull.signal();
             return x;
           } finally {
             lock.unlock();
           }
         }
       }
    

    结构

    ReentrantLock只是简单的实现了Lock接口和Serializable接口。
    从实现上来看,ReentrantLock更像是一个装饰器,其核心功能主要依赖内部的 Sync sync 变量,其中Sync的实现包括公平锁FairSync和非公平锁NonFairSync。Sync的实现里有一个重要的概念叫AQS(AbstractQueuedSynchronizer),我们将在下一片文章里单独讲解。

    image.png

    参考资料

    https://javarevisited.blogspot.com/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

    相关文章

      网友评论

          本文标题:java锁机制之「ReentrantLock」

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