package java.util.concurrent; /** * Utility operations for built-in synchronization and {@link Lock} classes. *

The Locks class defines utility methods that enhance the * use of synchronized methods and statements by: *

*

An additional convenience method is provided to acquire multiple * {@link Lock} instances only if they are all available. *

To preserve the block-structured locking that is required for the * built-in monitor locks, each method takes a {@link Runnable} action as * an argument and executes its {@link Runnable#run run} method with the * appropriate locks held. * When the {@link Runnable#run run} method completes all locks * are released. * *

Note: All methods that take {@link Object} parameters treat * those parameters as {@link Object Objects}, even if they happen to be * {@link Lock} instances. These methods will always acquire the monitor * lock of the given object - they will not perform a {@link Lock#lock} * invocation. * *

Except where noted, passing a null value for any parameter * will result in a {@link NullPointerException} being thrown. * *

Memory Synchronization

*

When a {@link Runnable} object's {@link Runnable#run run} method is * executed it means that the appropriate * lock (or locks) has been acquired, and so the memory synchronization * effects of acquiring that lock will have taken place. Similarly, when * the {@link Runnable} object's {@link Runnable#run run} method completes, * the lock (or locks) is released and the associated memory synchronization * effects will take place. Exactly what those memory synchronization * effects are will depend on the nature of the lock and the type of * acquisition/release - for example, reentrantly acquiring a monitor lock * has no associated memory synchronization effects. *

When mutliple locks are involved it may be that some of the locks are * acquired and subsequently released, before an unavailable lock is found. * In that case the memory synchronization effects will be those of the locks * that were actually acquired and actually released. * * @since 1.5 * @spec JSR-166 * @revised $Date: 2003/05/14 21:30:47 $ * @editor $Author: tim $ * * @fixme add implementation notes for any performance issues related to * timeouts or interrupts **/ public class Locks { private Locks() {} // uninstantiable. /** * Performs the given action holding the monitor lock of * the given object only if that lock is currently free. * *

If the monitor lock of the given object is immediately available * to the current thread then it is acquired. * The action is then executed and finally the monitor lock is released * and the method returns with the value true. *

If the monitor lock is not available then the method returns * immediately with the value false. *

If the action completes abruptly due to an {@link Error} or * {@link RuntimeException}, then the method completes abruptly * for the same reason, after the lock has been released. * * @param lock the object whose monitor lock must be acquired * @param action the code to run while holding the monitor lock * @return true if the action was executed, and false * otherwise. **/ public static boolean attempt(Object lock, Runnable action) { return false; // for now; } /** * Performs the given action holding the monitor lock of * the given object if it is free within the given waiting time and the * current thread has not been {@link Thread#interrupt interrupted}. * *

If the monitor lock of the given object is immediately available * to the current thread then it is acquired. * The action is then executed and finally the monitor lock is released * and the method returns with the value true. * *

If the monitor lock is not available then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until one of three things happens: *

*

If the monitor lock is acquired * the action is executed then the monitor lock is released * and the method returns with the value true. * *

If the action completes abruptly due to an {@link Error} or * {@link RuntimeException}, then the method completes abruptly * for the same reason, after the lock has been released. * *

If the current thread: *

* then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * *

If the specified waiting time elapses then the value false * is returned. * The given waiting time is a best-effort lower bound. If the time is * less than or equal to zero, the method will not wait at all. * *

Implementation Notes *

TO-BE-DONE * * * @param lock the object whose monitor lock must be acquired * @param action the code to run while holding the monitor lock * @param timeout the maximum time to wait for the monitor lock * @param granularity the time unit of the timeout argument. * @return true if the monitor lock was acquired and the * action executed, and false * if the waiting time elapsed before the monitor lock was acquired. * * @throws InterruptedException if the current thread is interrupted * while trying to acquire the monitor lock. * * @see Thread#interrupt * **/ public static boolean attempt(Object lock, Runnable action, long timeout, TimeUnit granularity) throws InterruptedException { return false; // for now; } /** * Performs the given action holding the monitor locks of * the given objects only if those locks are currently free. * *

If the monitor locks of each object in the array are immediately * available to the current thread then they are acquired. * The action is then executed and finally the monitor locks are released * and the method returns with the value true. *

If any of the monitor locks is not available then * all previously acquired monitor locks are released and the method * returns with the value false. *

If the action completes abruptly due to an {@link Error} or * {@link RuntimeException}, then the method completes abruptly * for the same reason, after all the locks have been released. * * @param locks the objects whose monitor locks must be acquired * @param action the code to run while holding the monitor locks * @return true if the action was executed, and false * otherwise. * * @throws NullPointerException if an attempt is made to acquire the * monitor lock of a null element in the locks array. **/ public static boolean attempt(Object[] locks, Runnable action) { return false; // for now; } /** * Performs the given action holding the given {@link Lock} instances, only * if those {@link Lock} instances are currently free. * *

If each of the locks in the array are immediately * available to the current thread then they are acquired. * The action is then executed and finally the locks are * released and the method returns with the value true. *

If any of the locks are not available then * all previously acquired locks are released and the * method returns immediately with the value false. *

If the action completes abruptly due to an {@link Error} or * {@link RuntimeException}, then the method completes abruptly * for the same reason, after all the locks have been * released. * * @param locks the {@link Lock} instances that must be acquired * @param action the code to run while holding the given locks * @return true if the action was executed, and false * otherwise. * * @throws NullPointerException if an attempt is made to acquire the * lock of a null element in the locks array. **/ public static boolean attempt(Lock[] locks, Runnable action) { return false; // for now; } /** * Returns a {@link Condition} instance for use with the given object. *

The returned {@link Condition} instance has analagous behavior * to the use of the monitor methods on the given object. Given *

    Condition c = Locks.newConditionFor(o);
     * 
* then: * * in that: * *

A {@link Condition} instance obtained in this way can be used to * create the * affect of having additional monitor wait-sets for the given object. * For example, suppose we have a bounded buffer which supports methods * to put and take items in/from the buffer. If a * take is attempted on an empty buffer then the thread will block * until an item becomes available; if a put is attempted on a * full buffer, then the thread will block until a space becomes available. * We would like to keep waiting put threads and take * threads in separate wait-sets so that we can use the optimisation of * only notifying a single thread at a time when items, or spaces, become * available in the buffer. This can be achieved using either two * {@link Condition} instances, or one {@link Condition} instance and the * actual * monitor wait-set. For clarity we'll use two {@link Condition} instances. *


     * class BoundedBuffer {
     *   final Condition notFull  = Locks.newConditionFor(this); 
     *   final Condition notEmpty = Locks.newConditionFor(this); 
     *
     *   Object[] items = new Object[100];
     *   int putptr, takeptr, count;
     *
     *   public synchronized void put(Object x) 
     *                              throws InterruptedException {
     *     while (count == items.length) 
     *       notFull.await();
     *     items[putptr] = x; 
     *     if (++putptr == items.length) putptr = 0;
     *     ++count;
     *     notEmpty.signal();
     *   }
     *
     *   public synchronized Object take() throws InterruptedException {
     *     while (count == 0) 
     *       notEmpty.await();
     *     Object x = items[takeptr]; 
     *     if (++takeptr == items.length) takeptr = 0;
     *     --count;
     *     notFull.signal();
     *     return x;
     *   } 
     * }
     * 
* * @param lock the object that will be used for its monitor lock and to * which the returned condition should be bound. * @return a {@link Condition} instance bound to the given object **/ public static Condition newConditionFor(Object lock) { return null; // for now; } }