Class NonReentrantLock

  • All Implemented Interfaces:
    java.io.Serializable, java.util.concurrent.locks.Lock

    final class NonReentrantLock
    extends java.lang.Object
    implements java.util.concurrent.locks.Lock, java.io.Serializable
    A non-reentrant mutual exclusion Lock. This type of lock does not allow recursive locks held by the same thread and will deadlock if used recursively. This type of lock is useful when reentrancy is not required and a slim lock is desired.

    A NonReentrantLock is owned by the thread last successfully locking, but not yet unlocking it. A thread invoking lock will return, successfully acquiring the lock, when the lock is not owned by another thread. This can be checked using methods isHeldByCurrentThread().

    It is recommended practice to always immediately follow a call to lock with a try block, most typically in a before/after construction such as:

     
     class X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...
    
       public void m() {
         lock.lock();  // block until condition holds
         try {
           // ... method body
         } finally {
           lock.unlock()
         }
       }
     }
     

    In addition to implementing the Lock interface, this class defines a number of public and protected methods for inspecting the state of the lock. Some of these methods are only useful for instrumentation and monitoring.

    Serialization of this class behaves in the same way as built-in locks: a deserialized lock is in the unlocked state, regardless of its state when serialized.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      (package private) static class  NonReentrantLock.Sync
      A non-fair lock using AQS state to represent if the lock is held.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.lang.Thread getOwner()
      Returns the thread that currently owns this lock, or null if not owned.
      java.util.Collection<java.lang.Thread> getQueuedThreads()
      Returns a collection containing threads that may be waiting to acquire this lock.
      int getQueueLength()
      Returns an estimate of the number of threads waiting to acquire this lock.
      java.util.Collection<java.lang.Thread> getWaitingThreads​(java.util.concurrent.locks.Condition condition)
      Returns a collection containing those threads that may be waiting on the given condition associated with this lock.
      int getWaitQueueLength​(java.util.concurrent.locks.Condition condition)
      Returns an estimate of the number of threads waiting on the given condition associated with this lock.
      boolean hasQueuedThread​(java.lang.Thread thread)
      Queries whether the given thread is waiting to acquire this lock.
      boolean hasQueuedThreads()
      Queries whether any threads are waiting to acquire this lock.
      boolean hasWaiters​(java.util.concurrent.locks.Condition condition)
      Queries whether any threads are waiting on the given condition associated with this lock.
      boolean isHeldByCurrentThread()
      Queries if this lock is held by the current thread.
      boolean isLocked()
      Queries if this lock is held by any thread.
      void lock()  
      void lockInterruptibly()  
      java.util.concurrent.locks.Condition newCondition()  
      java.lang.String toString()
      Returns a string identifying this lock, as well as its lock state.
      boolean tryLock()  
      boolean tryLock​(long time, java.util.concurrent.TimeUnit unit)  
      void unlock()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • NonReentrantLock

        public NonReentrantLock()
    • Method Detail

      • lock

        public void lock()
        Specified by:
        lock in interface java.util.concurrent.locks.Lock
      • lockInterruptibly

        public void lockInterruptibly()
                               throws java.lang.InterruptedException
        Specified by:
        lockInterruptibly in interface java.util.concurrent.locks.Lock
        Throws:
        java.lang.InterruptedException
      • tryLock

        public boolean tryLock()
        Specified by:
        tryLock in interface java.util.concurrent.locks.Lock
      • tryLock

        public boolean tryLock​(long time,
                               java.util.concurrent.TimeUnit unit)
                        throws java.lang.InterruptedException
        Specified by:
        tryLock in interface java.util.concurrent.locks.Lock
        Throws:
        java.lang.InterruptedException
      • unlock

        public void unlock()
        Specified by:
        unlock in interface java.util.concurrent.locks.Lock
      • newCondition

        public java.util.concurrent.locks.Condition newCondition()
        Specified by:
        newCondition in interface java.util.concurrent.locks.Lock
      • isHeldByCurrentThread

        public boolean isHeldByCurrentThread()
        Queries if this lock is held by the current thread.

        Analogous to the Thread.holdsLock(Object) method for built-in monitor locks, this method is typically used for debugging and testing. For example, a method that should only be called while a lock is held can assert that this is the case:

         {
           @code
           class X {
             ReentrantLock lock = new ReentrantLock();
        
             // ...
        
             public void m() {
               assert lock.isHeldByCurrentThread();
               // ... method body
             }
           }
         }
         

        It can also be used to ensure that a reentrant lock is used in a non-reentrant manner, for example:

         {
           @code
           class X {
             ReentrantLock lock = new ReentrantLock();
        
             // ...
        
             public void m() {
               assert !lock.isHeldByCurrentThread();
               lock.lock();
               try {
                 // ... method body
               } finally {
                 lock.unlock();
               }
             }
           }
         }
         
        Returns:
        true if current thread holds this lock and false otherwise
      • isLocked

        public boolean isLocked()
        Queries if this lock is held by any thread. This method is designed for use in monitoring of the system state, not for synchronization control.
        Returns:
        true if any thread holds this lock and false otherwise
      • getOwner

        public java.lang.Thread getOwner()
        Returns the thread that currently owns this lock, or null if not owned. When this method is called by a thread that is not the owner, the return value reflects a best-effort approximation of current lock status. For example, the owner may be momentarily null even if there are threads trying to acquire the lock but have not yet done so. This method is designed to facilitate construction of subclasses that provide more extensive lock monitoring facilities.
        Returns:
        the owner, or null if not owned
      • hasQueuedThreads

        public boolean hasQueuedThreads()
        Queries whether any threads are waiting to acquire this lock. Note that because cancellations may occur at any time, a true return does not guarantee that any other thread will ever acquire this lock. This method is designed primarily for use in monitoring of the system state.
        Returns:
        true if there may be other threads waiting to acquire the lock
      • hasQueuedThread

        public boolean hasQueuedThread​(java.lang.Thread thread)
        Queries whether the given thread is waiting to acquire this lock. Note that because cancellations may occur at any time, a true return does not guarantee that this thread will ever acquire this lock. This method is designed primarily for use in monitoring of the system state.
        Parameters:
        thread - the thread
        Returns:
        true if the given thread is queued waiting for this lock
        Throws:
        java.lang.NullPointerException - if the thread is null
      • getQueueLength

        public int getQueueLength()
        Returns an estimate of the number of threads waiting to acquire this lock. The value is only an estimate because the number of threads may change dynamically while this method traverses internal data structures. This method is designed for use in monitoring of the system state, not for synchronization control.
        Returns:
        the estimated number of threads waiting for this lock
      • getQueuedThreads

        public java.util.Collection<java.lang.Thread> getQueuedThreads()
        Returns a collection containing threads that may be waiting to acquire this lock. Because the actual set of threads may change dynamically while constructing this result, the returned collection is only a best-effort estimate. The elements of the returned collection are in no particular order. This method is designed to facilitate construction of subclasses that provide more extensive monitoring facilities.
        Returns:
        the collection of threads
      • hasWaiters

        public boolean hasWaiters​(java.util.concurrent.locks.Condition condition)
        Queries whether any threads are waiting on the given condition associated with this lock. Note that because timeouts and interrupts may occur at any time, a true return does not guarantee that a future signal will awaken any threads. This method is designed primarily for use in monitoring of the system state.
        Parameters:
        condition - the condition
        Returns:
        true if there are any waiting threads
        Throws:
        java.lang.IllegalMonitorStateException - if this lock is not held
        java.lang.IllegalArgumentException - if the given condition is not associated with this lock
        java.lang.NullPointerException - if the condition is null
      • getWaitQueueLength

        public int getWaitQueueLength​(java.util.concurrent.locks.Condition condition)
        Returns an estimate of the number of threads waiting on the given condition associated with this lock. Note that because timeouts and interrupts may occur at any time, the estimate serves only as an upper bound on the actual number of waiters. This method is designed for use in monitoring of the system state, not for synchronization control.
        Parameters:
        condition - the condition
        Returns:
        the estimated number of waiting threads
        Throws:
        java.lang.IllegalMonitorStateException - if this lock is not held
        java.lang.IllegalArgumentException - if the given condition is not associated with this lock
        java.lang.NullPointerException - if the condition is null
      • getWaitingThreads

        public java.util.Collection<java.lang.Thread> getWaitingThreads​(java.util.concurrent.locks.Condition condition)
        Returns a collection containing those threads that may be waiting on the given condition associated with this lock. Because the actual set of threads may change dynamically while constructing this result, the returned collection is only a best-effort estimate. The elements of the returned collection are in no particular order. This method is designed to facilitate construction of subclasses that provide more extensive condition monitoring facilities.
        Parameters:
        condition - the condition
        Returns:
        the collection of threads
        Throws:
        java.lang.IllegalMonitorStateException - if this lock is not held
        java.lang.IllegalArgumentException - if the given condition is not associated with this lock
        java.lang.NullPointerException - if the condition is null
      • toString

        public java.lang.String toString()
        Returns a string identifying this lock, as well as its lock state. The state, in brackets, includes either the String "Unlocked" or the String "Locked by" followed by the name of the owning thread.
        Overrides:
        toString in class java.lang.Object
        Returns:
        a string identifying this lock, as well as its lock state