Home | History | Annotate | Download | only in locks
      1 /*
      2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      3  *
      4  * This code is free software; you can redistribute it and/or modify it
      5  * under the terms of the GNU General Public License version 2 only, as
      6  * published by the Free Software Foundation.  Oracle designates this
      7  * particular file as subject to the "Classpath" exception as provided
      8  * by Oracle in the LICENSE file that accompanied this code.
      9  *
     10  * This code is distributed in the hope that it will be useful, but WITHOUT
     11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     13  * version 2 for more details (a copy is included in the LICENSE file that
     14  * accompanied this code).
     15  *
     16  * You should have received a copy of the GNU General Public License version
     17  * 2 along with this work; if not, write to the Free Software Foundation,
     18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     19  *
     20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     21  * or visit www.oracle.com if you need additional information or have any
     22  * questions.
     23  */
     24 
     25 /*
     26  * This file is available under and governed by the GNU General Public
     27  * License version 2 only, as published by the Free Software Foundation.
     28  * However, the following notice accompanied the original version of this
     29  * file:
     30  *
     31  * Written by Doug Lea with assistance from members of JCP JSR-166
     32  * Expert Group and released to the public domain, as explained at
     33  * http://creativecommons.org/publicdomain/zero/1.0/
     34  */
     35 
     36 package java.util.concurrent.locks;
     37 
     38 import java.util.concurrent.TimeUnit;
     39 
     40 /**
     41  * {@code Lock} implementations provide more extensive locking
     42  * operations than can be obtained using {@code synchronized} methods
     43  * and statements.  They allow more flexible structuring, may have
     44  * quite different properties, and may support multiple associated
     45  * {@link Condition} objects.
     46  *
     47  * <p>A lock is a tool for controlling access to a shared resource by
     48  * multiple threads. Commonly, a lock provides exclusive access to a
     49  * shared resource: only one thread at a time can acquire the lock and
     50  * all access to the shared resource requires that the lock be
     51  * acquired first. However, some locks may allow concurrent access to
     52  * a shared resource, such as the read lock of a {@link ReadWriteLock}.
     53  *
     54  * <p>The use of {@code synchronized} methods or statements provides
     55  * access to the implicit monitor lock associated with every object, but
     56  * forces all lock acquisition and release to occur in a block-structured way:
     57  * when multiple locks are acquired they must be released in the opposite
     58  * order, and all locks must be released in the same lexical scope in which
     59  * they were acquired.
     60  *
     61  * <p>While the scoping mechanism for {@code synchronized} methods
     62  * and statements makes it much easier to program with monitor locks,
     63  * and helps avoid many common programming errors involving locks,
     64  * there are occasions where you need to work with locks in a more
     65  * flexible way. For example, some algorithms for traversing
     66  * concurrently accessed data structures require the use of
     67  * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
     68  * acquire the lock of node A, then node B, then release A and acquire
     69  * C, then release B and acquire D and so on.  Implementations of the
     70  * {@code Lock} interface enable the use of such techniques by
     71  * allowing a lock to be acquired and released in different scopes,
     72  * and allowing multiple locks to be acquired and released in any
     73  * order.
     74  *
     75  * <p>With this increased flexibility comes additional
     76  * responsibility. The absence of block-structured locking removes the
     77  * automatic release of locks that occurs with {@code synchronized}
     78  * methods and statements. In most cases, the following idiom
     79  * should be used:
     80  *
     81  * <pre> {@code
     82  * Lock l = ...;
     83  * l.lock();
     84  * try {
     85  *   // access the resource protected by this lock
     86  * } finally {
     87  *   l.unlock();
     88  * }}</pre>
     89  *
     90  * When locking and unlocking occur in different scopes, care must be
     91  * taken to ensure that all code that is executed while the lock is
     92  * held is protected by try-finally or try-catch to ensure that the
     93  * lock is released when necessary.
     94  *
     95  * <p>{@code Lock} implementations provide additional functionality
     96  * over the use of {@code synchronized} methods and statements by
     97  * providing a non-blocking attempt to acquire a lock ({@link
     98  * #tryLock()}), an attempt to acquire the lock that can be
     99  * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
    100  * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
    101  *
    102  * <p>A {@code Lock} class can also provide behavior and semantics
    103  * that is quite different from that of the implicit monitor lock,
    104  * such as guaranteed ordering, non-reentrant usage, or deadlock
    105  * detection. If an implementation provides such specialized semantics
    106  * then the implementation must document those semantics.
    107  *
    108  * <p>Note that {@code Lock} instances are just normal objects and can
    109  * themselves be used as the target in a {@code synchronized} statement.
    110  * Acquiring the
    111  * monitor lock of a {@code Lock} instance has no specified relationship
    112  * with invoking any of the {@link #lock} methods of that instance.
    113  * It is recommended that to avoid confusion you never use {@code Lock}
    114  * instances in this way, except within their own implementation.
    115  *
    116  * <p>Except where noted, passing a {@code null} value for any
    117  * parameter will result in a {@link NullPointerException} being
    118  * thrown.
    119  *
    120  * <h3>Memory Synchronization</h3>
    121  *
    122  * <p>All {@code Lock} implementations <em>must</em> enforce the same
    123  * memory synchronization semantics as provided by the built-in monitor
    124  * lock, as described in
    125  * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
    126  * Chapter 17 of
    127  * <cite>The Java&trade; Language Specification</cite></a>:
    128  * <ul>
    129  * <li>A successful {@code lock} operation has the same memory
    130  * synchronization effects as a successful <em>Lock</em> action.
    131  * <li>A successful {@code unlock} operation has the same
    132  * memory synchronization effects as a successful <em>Unlock</em> action.
    133  * </ul>
    134  *
    135  * Unsuccessful locking and unlocking operations, and reentrant
    136  * locking/unlocking operations, do not require any memory
    137  * synchronization effects.
    138  *
    139  * <h3>Implementation Considerations</h3>
    140  *
    141  * <p>The three forms of lock acquisition (interruptible,
    142  * non-interruptible, and timed) may differ in their performance
    143  * characteristics, ordering guarantees, or other implementation
    144  * qualities.  Further, the ability to interrupt the <em>ongoing</em>
    145  * acquisition of a lock may not be available in a given {@code Lock}
    146  * class.  Consequently, an implementation is not required to define
    147  * exactly the same guarantees or semantics for all three forms of
    148  * lock acquisition, nor is it required to support interruption of an
    149  * ongoing lock acquisition.  An implementation is required to clearly
    150  * document the semantics and guarantees provided by each of the
    151  * locking methods. It must also obey the interruption semantics as
    152  * defined in this interface, to the extent that interruption of lock
    153  * acquisition is supported: which is either totally, or only on
    154  * method entry.
    155  *
    156  * <p>As interruption generally implies cancellation, and checks for
    157  * interruption are often infrequent, an implementation can favor responding
    158  * to an interrupt over normal method return. This is true even if it can be
    159  * shown that the interrupt occurred after another action may have unblocked
    160  * the thread. An implementation should document this behavior.
    161  *
    162  * @see ReentrantLock
    163  * @see Condition
    164  * @see ReadWriteLock
    165  *
    166  * @since 1.5
    167  * @author Doug Lea
    168  */
    169 public interface Lock {
    170 
    171     /**
    172      * Acquires the lock.
    173      *
    174      * <p>If the lock is not available then the current thread becomes
    175      * disabled for thread scheduling purposes and lies dormant until the
    176      * lock has been acquired.
    177      *
    178      * <p><b>Implementation Considerations</b>
    179      *
    180      * <p>A {@code Lock} implementation may be able to detect erroneous use
    181      * of the lock, such as an invocation that would cause deadlock, and
    182      * may throw an (unchecked) exception in such circumstances.  The
    183      * circumstances and the exception type must be documented by that
    184      * {@code Lock} implementation.
    185      */
    186     void lock();
    187 
    188     /**
    189      * Acquires the lock unless the current thread is
    190      * {@linkplain Thread#interrupt interrupted}.
    191      *
    192      * <p>Acquires the lock if it is available and returns immediately.
    193      *
    194      * <p>If the lock is not available then the current thread becomes
    195      * disabled for thread scheduling purposes and lies dormant until
    196      * one of two things happens:
    197      *
    198      * <ul>
    199      * <li>The lock is acquired by the current thread; or
    200      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
    201      * current thread, and interruption of lock acquisition is supported.
    202      * </ul>
    203      *
    204      * <p>If the current thread:
    205      * <ul>
    206      * <li>has its interrupted status set on entry to this method; or
    207      * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
    208      * lock, and interruption of lock acquisition is supported,
    209      * </ul>
    210      * then {@link InterruptedException} is thrown and the current thread's
    211      * interrupted status is cleared.
    212      *
    213      * <p><b>Implementation Considerations</b>
    214      *
    215      * <p>The ability to interrupt a lock acquisition in some
    216      * implementations may not be possible, and if possible may be an
    217      * expensive operation.  The programmer should be aware that this
    218      * may be the case. An implementation should document when this is
    219      * the case.
    220      *
    221      * <p>An implementation can favor responding to an interrupt over
    222      * normal method return.
    223      *
    224      * <p>A {@code Lock} implementation may be able to detect
    225      * erroneous use of the lock, such as an invocation that would
    226      * cause deadlock, and may throw an (unchecked) exception in such
    227      * circumstances.  The circumstances and the exception type must
    228      * be documented by that {@code Lock} implementation.
    229      *
    230      * @throws InterruptedException if the current thread is
    231      *         interrupted while acquiring the lock (and interruption
    232      *         of lock acquisition is supported)
    233      */
    234     void lockInterruptibly() throws InterruptedException;
    235 
    236     /**
    237      * Acquires the lock only if it is free at the time of invocation.
    238      *
    239      * <p>Acquires the lock if it is available and returns immediately
    240      * with the value {@code true}.
    241      * If the lock is not available then this method will return
    242      * immediately with the value {@code false}.
    243      *
    244      * <p>A typical usage idiom for this method would be:
    245      * <pre> {@code
    246      * Lock lock = ...;
    247      * if (lock.tryLock()) {
    248      *   try {
    249      *     // manipulate protected state
    250      *   } finally {
    251      *     lock.unlock();
    252      *   }
    253      * } else {
    254      *   // perform alternative actions
    255      * }}</pre>
    256      *
    257      * This usage ensures that the lock is unlocked if it was acquired, and
    258      * doesn't try to unlock if the lock was not acquired.
    259      *
    260      * @return {@code true} if the lock was acquired and
    261      *         {@code false} otherwise
    262      */
    263     boolean tryLock();
    264 
    265     /**
    266      * Acquires the lock if it is free within the given waiting time and the
    267      * current thread has not been {@linkplain Thread#interrupt interrupted}.
    268      *
    269      * <p>If the lock is available this method returns immediately
    270      * with the value {@code true}.
    271      * If the lock is not available then
    272      * the current thread becomes disabled for thread scheduling
    273      * purposes and lies dormant until one of three things happens:
    274      * <ul>
    275      * <li>The lock is acquired by the current thread; or
    276      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
    277      * current thread, and interruption of lock acquisition is supported; or
    278      * <li>The specified waiting time elapses
    279      * </ul>
    280      *
    281      * <p>If the lock is acquired then the value {@code true} is returned.
    282      *
    283      * <p>If the current thread:
    284      * <ul>
    285      * <li>has its interrupted status set on entry to this method; or
    286      * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
    287      * the lock, and interruption of lock acquisition is supported,
    288      * </ul>
    289      * then {@link InterruptedException} is thrown and the current thread's
    290      * interrupted status is cleared.
    291      *
    292      * <p>If the specified waiting time elapses then the value {@code false}
    293      * is returned.
    294      * If the time is
    295      * less than or equal to zero, the method will not wait at all.
    296      *
    297      * <p><b>Implementation Considerations</b>
    298      *
    299      * <p>The ability to interrupt a lock acquisition in some implementations
    300      * may not be possible, and if possible may
    301      * be an expensive operation.
    302      * The programmer should be aware that this may be the case. An
    303      * implementation should document when this is the case.
    304      *
    305      * <p>An implementation can favor responding to an interrupt over normal
    306      * method return, or reporting a timeout.
    307      *
    308      * <p>A {@code Lock} implementation may be able to detect
    309      * erroneous use of the lock, such as an invocation that would cause
    310      * deadlock, and may throw an (unchecked) exception in such circumstances.
    311      * The circumstances and the exception type must be documented by that
    312      * {@code Lock} implementation.
    313      *
    314      * @param time the maximum time to wait for the lock
    315      * @param unit the time unit of the {@code time} argument
    316      * @return {@code true} if the lock was acquired and {@code false}
    317      *         if the waiting time elapsed before the lock was acquired
    318      *
    319      * @throws InterruptedException if the current thread is interrupted
    320      *         while acquiring the lock (and interruption of lock
    321      *         acquisition is supported)
    322      */
    323     boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    324 
    325     /**
    326      * Releases the lock.
    327      *
    328      * <p><b>Implementation Considerations</b>
    329      *
    330      * <p>A {@code Lock} implementation will usually impose
    331      * restrictions on which thread can release a lock (typically only the
    332      * holder of the lock can release it) and may throw
    333      * an (unchecked) exception if the restriction is violated.
    334      * Any restrictions and the exception
    335      * type must be documented by that {@code Lock} implementation.
    336      */
    337     void unlock();
    338 
    339     /**
    340      * Returns a new {@link Condition} instance that is bound to this
    341      * {@code Lock} instance.
    342      *
    343      * <p>Before waiting on the condition the lock must be held by the
    344      * current thread.
    345      * A call to {@link Condition#await()} will atomically release the lock
    346      * before waiting and re-acquire the lock before the wait returns.
    347      *
    348      * <p><b>Implementation Considerations</b>
    349      *
    350      * <p>The exact operation of the {@link Condition} instance depends on
    351      * the {@code Lock} implementation and must be documented by that
    352      * implementation.
    353      *
    354      * @return A new {@link Condition} instance for this {@code Lock} instance
    355      * @throws UnsupportedOperationException if this {@code Lock}
    356      *         implementation does not support conditions
    357      */
    358     Condition newCondition();
    359 }
    360