ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Locks.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/Locks.java (file contents):
Revision 1.1 by tim, Wed May 14 21:30:47 2003 UTC vs.
Revision 1.2 by dl, Tue May 27 18:14:40 2003 UTC

# Line 1 | Line 1
1 < package java.util.concurrent;
1 > /*
2 > * Written by Doug Lea with assistance from members of JCP JSR-166
3 > * Expert Group and released to the public domain. Use, modify, and
4 > * redistribute this code in any way without acknowledgement.
5 > */
6  
7 + package java.util.concurrent;
8 + import sun.misc.Unsafe;
9 + import java.util.Date;
10  
11   /**
12   * Utility operations for built-in synchronization and {@link Lock} classes.
# Line 55 | Line 62 | package java.util.concurrent;
62   * timeouts or interrupts
63   **/
64   public class Locks {
58
65      private Locks() {} // uninstantiable.
66  
67      /**
# Line 78 | Line 84 | public class Locks {
84       * otherwise.
85       **/
86      public static boolean attempt(Object lock, Runnable action) {
87 <        return false; // for now;
88 <    }
87 >        if (lock == null || action == null)
88 >            throw new NullPointerException();
89  
90 <    /**
91 <     * Performs the given action holding the monitor lock of
92 <     * the given object if it is free within the given waiting time and the
93 <     * current thread has not been {@link Thread#interrupt interrupted}.
94 <     *
95 <     * <p>If the monitor lock of the given object is immediately available
96 <     * to the current thread then it is acquired.
97 <     * The action is then executed and finally the monitor lock is released
98 <     * and the method returns with the value <tt>true</tt>.
99 <     *
94 <     * <p>If the monitor lock is not available then
95 <     * the current thread becomes disabled for thread scheduling
96 <     * purposes and lies dormant until one of three things happens:
97 <     * <ul>
98 <     * <li> The monitor lock is acquired by the current thread; or
99 <     * <li> Some other thread {@link Thread#interrupt interrupts} the current
100 <     * thread; or
101 <     * <li> The specified waiting time elapses
102 <     * </ul>
103 <     * <p>If the monitor lock is acquired
104 <     * the action is executed then the monitor lock is released
105 <     * and the method returns with the value <tt>true</tt>.
106 <     *
107 <     * <p>If the action completes abruptly due to an {@link Error} or
108 <     * {@link RuntimeException}, then the method completes abruptly
109 <     * for the same reason, after the lock has been released.
110 <     *
111 <     * <p>If the current thread:
112 <     * <ul>
113 <     * <li>has its interrupted status set on entry to this method; or
114 <     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
115 <     * the monitor lock,
116 <     * </ul>
117 <     * then {@link InterruptedException} is thrown and the current thread's
118 <     * interrupted status is cleared.
119 <     *
120 <     * <p>If the specified waiting time elapses then the value <tt>false</tt>
121 <     * is returned.
122 <     * The given waiting time is a best-effort lower bound. If the time is
123 <     * less than or equal to zero, the method will not wait at all.
124 <     *
125 <     * <p><b>Implementation Notes</b>
126 <     * <p>TO-BE-DONE
127 <     *
128 <     *
129 <     * @param lock the object whose monitor lock must be acquired
130 <     * @param action the code to run while holding the monitor lock
131 <     * @param timeout the maximum time to wait for the monitor lock
132 <     * @param granularity the time unit of the <tt>timeout</tt> argument.
133 <     * @return <tt>true</tt> if the monitor lock was acquired and the
134 <     * action executed, and <tt>false</tt>
135 <     * if the waiting time elapsed before the monitor lock was acquired.
136 <     *
137 <     * @throws InterruptedException if the current thread is interrupted
138 <     * while trying to acquire the monitor lock.
139 <     *
140 <     * @see Thread#interrupt
141 <     *
142 <     **/
143 <    public static boolean attempt(Object lock, Runnable action,
144 <                                  long timeout, TimeUnit granularity)
145 <        throws InterruptedException {
146 <
147 <        return false; // for now;
90 >        if (!JSR166Support.tryLockEnter(lock))
91 >            return false;
92 >        
93 >        try {
94 >            action.run();
95 >            return true;
96 >        }
97 >        finally {
98 >            JSR166Support.tryLockExit(lock);
99 >        }
100      }
101  
102      /**
# Line 171 | Line 123 | public class Locks {
123       * monitor lock of a <tt>null</tt> element in the <tt>locks</tt> array.
124       **/
125      public static boolean attempt(Object[] locks, Runnable action) {
126 <        return false; // for now;
126 >        // This code is a little mysterious looking unless you remember
127 >        // that finally clauses execute before return or throw.
128 >        int lastlocked = -1;
129 >        try {
130 >            boolean ok = true;
131 >            for (int i = 0; i < locks.length; ++i) {
132 >                Object l = locks[i];
133 >                if (l == null)
134 >                    throw new NullPointerException();
135 >                if (!JSR166Support.tryLockEnter(l))
136 >                    return false;
137 >                lastlocked = i;
138 >            }
139 >            action.run();
140 >            return true;
141 >        }
142 >        finally {
143 >            for (int i = lastlocked; i >= 0; --i)
144 >                JSR166Support.tryLockExit(locks[i]);
145 >        }
146      }
147  
148      /**
# Line 199 | Line 170 | public class Locks {
170       * lock of a <tt>null</tt> element in the <tt>locks</tt> array.
171       **/
172      public static boolean attempt(Lock[] locks, Runnable action) {
173 <        return false; // for now;
173 >        // This code is a little mysterious looking unless you remember
174 >        // that finally clauses execute before return or throw.
175 >        int lastlocked = -1;
176 >        try {
177 >            for (int i = 0; i < locks.length; ++i) {
178 >                Lock l = locks[i];
179 >                if (l == null)
180 >                    throw new NullPointerException();
181 >                if (!l.tryLock())
182 >                    return false;
183 >                lastlocked = i;
184 >            }
185 >
186 >            action.run();
187 >            return true;
188 >        }
189 >        finally {
190 >            for (int i = lastlocked; i >= 0; --i)
191 >                locks[i].unlock();
192 >        }
193      }
194  
195 +    /**
196 +     * Returns a conservative indicator of whether the given lock is
197 +     * held by any thread. This method always returns true if
198 +     * the lock is held, but may return true even if not held.
199 +     *
200 +     * @return true if lock is held, and either true or false if not held.
201 +     */
202 +    public static boolean mightBeLocked(Object lock) {
203 +        return JSR166Support.mightBeLocked(lock);
204 +    }
205  
206      /**
207       * Returns a {@link Condition} instance for use with the given object.
# Line 211 | Line 211 | public class Locks {
211       * </pre>
212       * then:
213       * <ul>
214 <     * <li><tt>c.await()</tt> is analagous to <tt>o.wait()</tt>
215 <     * <li><tt>c.signal()</tt> is analagous to <tt>o.notify()</tt>; and
216 <     * <li><tt>c.signalAll()</tt> is analagous to <tt>o.notifyAll()</tt>
214 >     * <li><tt>c.await()</tt> is analogous to <tt>o.wait()</tt>
215 >     * <li><tt>c.signal()</tt> is analogous to <tt>o.notify()</tt>; and
216 >     * <li><tt>c.signalAll()</tt> is analogous to <tt>o.notifyAll()</tt>
217       * </ul>
218       * in that:
219       * <ul>
# Line 284 | Line 284 | public class Locks {
284       * @return a {@link Condition} instance bound to the given object
285       **/
286      public static Condition newConditionFor(Object lock) {
287 <        return null; // for now;
287 >        return new ConditionObject(lock);
288      }
289  
290 < }
291 <
292 <
293 <
290 >    static final private class ConditionObject implements Condition {
291 >        private final Object lock;
292 >        private final Object cond = new Object();
293 >
294 >        ConditionObject(Object lock) { this.lock = lock; }
295 >
296 >        public void await() throws InterruptedException {
297 >            JSR166Support.conditionWait(lock, cond);
298 >        }
299 >
300 >        public void awaitUninterruptibly() {
301 >            boolean wasInterrupted = Thread.interrupted(); // record and clear
302 >            for (;;) {
303 >                try {
304 >                    JSR166Support.conditionWait(lock, cond);
305 >                    break;
306 >                }
307 >                catch (InterruptedException ex) { // re-interrupted; try again
308 >                    wasInterrupted = true;
309 >                }
310 >            }
311 >            if (wasInterrupted) { // re-establish interrupted state
312 >                Thread.currentThread().interrupt();
313 >            }
314 >        }
315 >
316 >        public long awaitNanos(long nanos) throws InterruptedException {
317 >            return JSR166Support.conditionRelWait(lock, cond, nanos);
318 >        }
319 >
320 >        public boolean await(long time, TimeUnit unit) throws InterruptedException {
321 >            return awaitNanos(unit.toNanos(time)) > 0;
322 >        }
323 >
324 >        public boolean awaitUntil(Date deadline) throws InterruptedException {
325 >            return JSR166Support.conditionAbsWait(lock, cond,
326 >                                                  deadline.getTime());
327 >        }
328 >        public void signal() {
329 >            JSR166Support.conditionNotify(lock, cond);
330 >        }
331 >
332 >        public void signalAll() {
333 >            JSR166Support.conditionNotifyAll(lock, cond);
334 >        }
335 >    }
336  
337 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines