Source Code Cross Referenced for ReentrantLock.java in  » Database-ORM » openjpa » org » apache » openjpa » lib » util » concurrent » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » openjpa » org.apache.openjpa.lib.util.concurrent 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.    
018:         */
019:        /*
020:         * Written by Doug Lea with assistance from members of JCP JSR-166
021:         * Expert Group and released to the public domain, as explained at
022:         * http://creativecommons.org/licenses/publicdomain
023:         */
024:        package org.apache.openjpa.lib.util.concurrent;
025:
026:        import java.util.Collection;
027:
028:        /**
029:         * A reentrant mutual exclusion {@link Lock} with the same basic
030:         * behavior and semantics as the implicit monitor lock accessed using
031:         * <tt>synchronized</tt> methods and statements, but with extended capabilities.
032:         * A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
033:         * successfully locking, but not yet unlocking it. A thread invoking
034:         * <tt>lock</tt> will return, successfully acquiring the lock, when
035:         * the lock is not owned by another thread. The method will return
036:         * immediately if the current thread already owns the lock. This can
037:         * be checked using methods {@link #isHeldByCurrentThread}, and {@link
038:         * #getHoldCount}. The constructor for this class accepts an optional
039:         * <em>fairness</em> parameter. When set <tt>true</tt>, under
040:         * contention, locks favor granting access to the longest-waiting
041:         * thread. Otherwise this lock does not guarantee any particular
042:         * access order. Programs using fair locks accessed by many threads
043:         * may display lower overall throughput(i.e., are slower; often much
044:         * slower) than those using the default setting, but have smaller
045:         * variances in times to obtain locks and guarantee lack of
046:         * starvation. Note however, that fairness of locks does not guarantee
047:         * fairness of thread scheduling. Thus, one of many threads using a
048:         * fair lock may obtain it multiple times in succession while other
049:         * active threads are not progressing and not currently holding the lock.
050:         * Also note that the untimed {@link #tryLock() tryLock} method does not
051:         * honor the fairness setting. It will succeed if the lock
052:         * is available even if other threads are waiting.
053:         * It is recommended practice to <em>always</em> immediately
054:         * follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
055:         * typically in a before/after construction such as:
056:         * 
057:         * <pre> class X { private final ReentrantLock lock = new ReentrantLock();
058:         * // ... public void m() { lock.lock(); // block until condition holds try {
059:         * // ... method body } finally { lock.unlock() } } }
060:         * </pre> In addition to implementing the {@link Lock} interface, this
061:         * class defines methods <tt>isLocked</tt> and
062:         * <tt>getLockQueueLength</tt>, as well as some associated
063:         * <tt>protected</tt> access methods that may be useful for
064:         * instrumentation and monitoring.
065:         * Serialization of this class behaves in the same way as built-in
066:         * locks: a deserialized lock is in the unlocked state, regardless of
067:         * its state when serialized.
068:         * This lock supports a maximum of 2147483647 recursive locks by
069:         * the same thread. Attempts to exceed this limit result in
070:         * {@link Error} throws from locking methods.
071:         *
072:         * @author Doug Lea
073:         * @author Dawid Kurzyniec
074:         * @since 1.5
075:         */
076:        public class ReentrantLock implements  Lock, java.io.Serializable,
077:                CondVar.ExclusiveLock {
078:
079:            private static final long serialVersionUID = 7373984872572414699L;
080:
081:            private final Sync sync;
082:
083:            static abstract class Sync implements  java.io.Serializable {
084:
085:                private static final long serialVersionUID = -5179523762034025860L;
086:
087:                protected transient Thread owner_ = null;
088:                protected transient int holds_ = 0;
089:
090:                protected Sync() {
091:                }
092:
093:                public abstract void lock();
094:
095:                public abstract void lockInterruptibly()
096:                        throws InterruptedException;
097:
098:                final void incHolds() {
099:                    int nextHolds = ++holds_;
100:                    if (nextHolds < 0)
101:                        throw new Error("Maximum lock count exceeded");
102:                    holds_ = nextHolds;
103:                }
104:
105:                public boolean tryLock() {
106:                    Thread caller = Thread.currentThread();
107:                    synchronized (this ) {
108:                        if (owner_ == null) {
109:                            owner_ = caller;
110:                            holds_ = 1;
111:                            return true;
112:                        } else if (caller == owner_) {
113:                            incHolds();
114:                            return true;
115:                        }
116:                    }
117:                    return false;
118:                }
119:
120:                public abstract boolean tryLock(long nanos)
121:                        throws InterruptedException;
122:
123:                public abstract void unlock();
124:
125:                public synchronized int getHoldCount() {
126:                    return isHeldByCurrentThread() ? holds_ : 0;
127:                }
128:
129:                public synchronized boolean isHeldByCurrentThread() {
130:                    return holds_ > 0 && Thread.currentThread() == owner_;
131:                }
132:
133:                public synchronized boolean isLocked() {
134:                    return owner_ != null;
135:                }
136:
137:                public abstract boolean isFair();
138:
139:                protected synchronized Thread getOwner() {
140:                    return owner_;
141:                }
142:
143:                public boolean hasQueuedThreads() {
144:                    throw new UnsupportedOperationException("Use FAIR version");
145:                }
146:
147:                public int getQueueLength() {
148:                    throw new UnsupportedOperationException("Use FAIR version");
149:                }
150:
151:                public Collection getQueuedThreads() {
152:                    throw new UnsupportedOperationException("Use FAIR version");
153:                }
154:
155:                public boolean isQueued(Thread thread) {
156:                    throw new UnsupportedOperationException("Use FAIR version");
157:                }
158:            }
159:
160:            final static class NonfairSync extends Sync {
161:
162:                private static final long serialVersionUID = 7316153563782823691L;
163:
164:                NonfairSync() {
165:                }
166:
167:                public void lock() {
168:                    Thread caller = Thread.currentThread();
169:                    synchronized (this ) {
170:                        if (owner_ == null) {
171:                            owner_ = caller;
172:                            holds_ = 1;
173:                            return;
174:                        } else if (caller == owner_) {
175:                            incHolds();
176:                            return;
177:                        } else {
178:                            boolean wasInterrupted = Thread.interrupted();
179:                            try {
180:                                while (true) {
181:                                    try {
182:                                        wait();
183:                                    } catch (InterruptedException e) {
184:                                        wasInterrupted = true;
185:                                        // no need to notify; if we were signalled, we
186:                                        // will act as signalled, ignoring the
187:                                        // interruption
188:                                    }
189:                                    if (owner_ == null) {
190:                                        owner_ = caller;
191:                                        holds_ = 1;
192:                                        return;
193:                                    }
194:                                }
195:                            } finally {
196:                                if (wasInterrupted)
197:                                    Thread.currentThread().interrupt();
198:                            }
199:                        }
200:                    }
201:                }
202:
203:                public void lockInterruptibly() throws InterruptedException {
204:                    if (Thread.interrupted())
205:                        throw new InterruptedException();
206:                    Thread caller = Thread.currentThread();
207:                    synchronized (this ) {
208:                        if (owner_ == null) {
209:                            owner_ = caller;
210:                            holds_ = 1;
211:                            return;
212:                        } else if (caller == owner_) {
213:                            incHolds();
214:                            return;
215:                        } else {
216:                            try {
217:                                do {
218:                                    wait();
219:                                } while (owner_ != null);
220:                                owner_ = caller;
221:                                holds_ = 1;
222:                                return;
223:                            } catch (InterruptedException ex) {
224:                                if (owner_ == null)
225:                                    notify();
226:                                throw ex;
227:                            }
228:                        }
229:                    }
230:                }
231:
232:                public boolean tryLock(long nanos) throws InterruptedException {
233:                    if (Thread.interrupted())
234:                        throw new InterruptedException();
235:                    Thread caller = Thread.currentThread();
236:
237:                    synchronized (this ) {
238:                        if (owner_ == null) {
239:                            owner_ = caller;
240:                            holds_ = 1;
241:                            return true;
242:                        } else if (caller == owner_) {
243:                            incHolds();
244:                            return true;
245:                        } else if (nanos <= 0)
246:                            return false;
247:                        else {
248:                            long deadline = Utils.nanoTime() + nanos;
249:                            try {
250:                                for (;;) {
251:                                    TimeUnit.NANOSECONDS.timedWait(this , nanos);
252:                                    if (caller == owner_) {
253:                                        incHolds();
254:                                        return true;
255:                                    } else if (owner_ == null) {
256:                                        owner_ = caller;
257:                                        holds_ = 1;
258:                                        return true;
259:                                    } else {
260:                                        nanos = deadline - Utils.nanoTime();
261:                                        if (nanos <= 0)
262:                                            return false;
263:                                    }
264:                                }
265:                            } catch (InterruptedException ex) {
266:                                if (owner_ == null)
267:                                    notify();
268:                                throw ex;
269:                            }
270:                        }
271:                    }
272:                }
273:
274:                public synchronized void unlock() {
275:                    if (Thread.currentThread() != owner_)
276:                        throw new IllegalMonitorStateException("Not owner");
277:
278:                    if (--holds_ == 0) {
279:                        owner_ = null;
280:                        notify();
281:                    }
282:                }
283:
284:                public final boolean isFair() {
285:                    return false;
286:                }
287:            }
288:
289:            final static class FairSync extends Sync implements 
290:                    WaitQueue.QueuedSync {
291:
292:                private static final long serialVersionUID = -3000897897090466540L;
293:
294:                private transient WaitQueue wq_ = new FIFOWaitQueue();
295:
296:                FairSync() {
297:                }
298:
299:                public synchronized boolean recheck(WaitQueue.WaitNode node) {
300:                    Thread caller = Thread.currentThread();
301:                    if (owner_ == null) {
302:                        owner_ = caller;
303:                        holds_ = 1;
304:                        return true;
305:                    } else if (caller == owner_) {
306:                        incHolds();
307:                        return true;
308:                    }
309:                    wq_.insert(node);
310:                    return false;
311:                }
312:
313:                public synchronized void takeOver(WaitQueue.WaitNode node) {
314:                    // assert(holds_ == 1 && owner_ == Thread.currentThread()
315:                    owner_ = node.getOwner();
316:                }
317:
318:                public void lock() {
319:                    Thread caller = Thread.currentThread();
320:                    synchronized (this ) {
321:                        if (owner_ == null) {
322:                            owner_ = caller;
323:                            holds_ = 1;
324:                            return;
325:                        } else if (caller == owner_) {
326:                            incHolds();
327:                            return;
328:                        }
329:                    }
330:                    WaitQueue.WaitNode n = new WaitQueue.WaitNode();
331:                    n.doWaitUninterruptibly(this );
332:                }
333:
334:                public void lockInterruptibly() throws InterruptedException {
335:                    if (Thread.interrupted())
336:                        throw new InterruptedException();
337:                    Thread caller = Thread.currentThread();
338:                    synchronized (this ) {
339:                        if (owner_ == null) {
340:                            owner_ = caller;
341:                            holds_ = 1;
342:                            return;
343:                        } else if (caller == owner_) {
344:                            incHolds();
345:                            return;
346:                        }
347:                    }
348:                    WaitQueue.WaitNode n = new WaitQueue.WaitNode();
349:                    n.doWait(this );
350:                }
351:
352:                public boolean tryLock(long nanos) throws InterruptedException {
353:                    if (Thread.interrupted())
354:                        throw new InterruptedException();
355:                    Thread caller = Thread.currentThread();
356:                    synchronized (this ) {
357:                        if (owner_ == null) {
358:                            owner_ = caller;
359:                            holds_ = 1;
360:                            return true;
361:                        } else if (caller == owner_) {
362:                            incHolds();
363:                            return true;
364:                        }
365:                    }
366:                    WaitQueue.WaitNode n = new WaitQueue.WaitNode();
367:                    return n.doTimedWait(this , nanos);
368:                }
369:
370:                protected synchronized WaitQueue.WaitNode getSignallee(
371:                        Thread caller) {
372:                    if (caller != owner_)
373:                        throw new IllegalMonitorStateException("Not owner");
374:                    // assert(holds_ > 0)
375:                    if (holds_ >= 2) { // current thread will keep the lock
376:                        --holds_;
377:                        return null;
378:                    }
379:                    // assert(holds_ == 1)
380:                    WaitQueue.WaitNode w = wq_.extract();
381:                    if (w == null) { // if none, clear for new arrivals
382:                        owner_ = null;
383:                        holds_ = 0;
384:                    }
385:                    return w;
386:                }
387:
388:                public void unlock() {
389:                    Thread caller = Thread.currentThread();
390:                    for (;;) {
391:                        WaitQueue.WaitNode w = getSignallee(caller);
392:                        if (w == null)
393:                            return; // no one to signal
394:                        if (w.signal(this ))
395:                            return; // notify if still waiting, or skip
396:                    }
397:                }
398:
399:                public final boolean isFair() {
400:                    return true;
401:                }
402:
403:                public synchronized boolean hasQueuedThreads() {
404:                    return wq_.hasNodes();
405:                }
406:
407:                public synchronized int getQueueLength() {
408:                    return wq_.getLength();
409:                }
410:
411:                public synchronized Collection getQueuedThreads() {
412:                    return wq_.getWaitingThreads();
413:                }
414:
415:                public synchronized boolean isQueued(Thread thread) {
416:                    return wq_.isWaiting(thread);
417:                }
418:
419:                private void readObject(java.io.ObjectInputStream in)
420:                        throws java.io.IOException, ClassNotFoundException {
421:                    in.defaultReadObject();
422:                    synchronized (this ) {
423:                        wq_ = new FIFOWaitQueue();
424:                    }
425:                }
426:            }
427:
428:            /**
429:             * Creates an instance of <tt>ReentrantLock</tt>.
430:             * This is equivalent to using <tt>ReentrantLock(false)</tt>.
431:             */
432:            public ReentrantLock() {
433:                sync = new NonfairSync();
434:            }
435:
436:            /**
437:             * Creates an instance of <tt>ReentrantLock</tt> with the
438:             * given fairness policy.
439:             *
440:             * @param fair true if this lock will be fair; else false
441:             */
442:            public ReentrantLock(boolean fair) {
443:                sync = (fair) ? (Sync) new FairSync() : new NonfairSync();
444:            }
445:
446:            /**
447:             * Acquires the lock.
448:             * Acquires the lock if it is not held by another thread and returns
449:             * immediately, setting the lock hold count to one. If the current thread
450:             * already holds the lock then the hold count is incremented by one and
451:             * the method returns immediately.
452:             * If the lock is held by another thread then the
453:             * current thread becomes disabled for thread scheduling
454:             * purposes and lies dormant until the lock has been acquired,
455:             * at which time the lock hold count is set to one.
456:             */
457:            public void lock() {
458:                sync.lock();
459:            }
460:
461:            /**
462:             * Acquires the lock unless the current thread is
463:             * {@link Thread#interrupt interrupted}.
464:             * Acquires the lock if it is not held by another thread and returns
465:             * immediately, setting the lock hold count to one.
466:             * If the current thread already holds this lock then the hold count
467:             * is incremented by one and the method returns immediately.
468:             * If the lock is held by another thread then the
469:             * current thread becomes disabled for thread scheduling
470:             * purposes and lies dormant until one of two things happens:
471:             * 
472:             * <ul>
473:             * 
474:             * <li>The lock is acquired by the current thread; or
475:             * 
476:             * <li>Some other thread {@link Thread#interrupt interrupts} the current
477:             * thread.
478:             * 
479:             * </ul> If the lock is acquired by the current thread then the lock hold
480:             * count is set to one. If the current thread:
481:             * 
482:             * <ul>
483:             * 
484:             * <li>has its interrupted status set on entry to this method; or
485:             * 
486:             * <li>is {@link Thread#interrupt interrupted} while acquiring the lock,
487:             * 
488:             * </ul>
489:             * then {@link InterruptedException} is thrown and the current thread's
490:             * interrupted status is cleared.
491:             * In this implementation, as this method is an explicit interruption
492:             * point, preference is
493:             * given to responding to the interrupt over normal or reentrant
494:             * acquisition of the lock.
495:             *
496:             * @throws InterruptedException if the current thread is interrupted
497:             */
498:            public void lockInterruptibly() throws InterruptedException {
499:                sync.lockInterruptibly();
500:            }
501:
502:            /**
503:             * Acquires the lock only if it is not held by another thread at the time
504:             * of invocation. Acquires the lock if it is not held by another thread and
505:             * returns immediately with the value <tt>true</tt>, setting the
506:             * lock hold count to one. Even when this lock has been set to use a
507:             * fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em>
508:             * immediately acquire the lock if it is available, whether or not
509:             * other threads are currently waiting for the lock.
510:             * This &quot;barging&quot; behavior can be useful in certain
511:             * circumstances, even though it breaks fairness. If you want to honor
512:             * the fairness setting for this lock, then use
513:             * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
514:             * which is almost equivalent(it also detects interruption).
515:             * If the current thread
516:             * already holds this lock then the hold count is incremented by one and
517:             * the method returns <tt>true</tt>.
518:             * If the lock is held by another thread then this method will return
519:             * immediately with the value <tt>false</tt>.
520:             *
521:             * @return <tt>true</tt> if the lock was free and was acquired by the
522:             * current thread, or the lock was already held by the current thread; and
523:             * <tt>false</tt> otherwise.
524:             */
525:            public boolean tryLock() {
526:                return sync.tryLock();
527:            }
528:
529:            /**
530:             * Acquires the lock if it is not held by another thread within the given
531:             * waiting time and the current thread has not been
532:             * {@link Thread#interrupt interrupted}.
533:             * Acquires the lock if it is not held by another thread and returns
534:             * immediately with the value <tt>true</tt>, setting the lock hold count
535:             * to one. If this lock has been set to use a fair ordering policy then
536:             * an available lock <em>will not</em> be acquired if any other threads
537:             * are waiting for the lock. This is in contrast to the {@link #tryLock()}
538:             * method. If you want a timed <tt>tryLock</tt> that does permit barging on
539:             * a fair lock then combine the timed and un-timed forms together:
540:             * 
541:             * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
542:             * </pre> If the current thread
543:             * already holds this lock then the hold count is incremented by one and
544:             * the method returns <tt>true</tt>.
545:             * If the lock is held by another thread then the
546:             * current thread becomes disabled for thread scheduling
547:             * purposes and lies dormant until one of three things happens:
548:             * 
549:             * <ul>
550:             * 
551:             * <li>The lock is acquired by the current thread; or
552:             * 
553:             * <li>Some other thread {@link Thread#interrupt interrupts} the current
554:             * thread; or
555:             * 
556:             * <li>The specified waiting time elapses
557:             * 
558:             * </ul>
559:             * If the lock is acquired then the value <tt>true</tt> is returned and
560:             * the lock hold count is set to one. If the current thread:
561:             * 
562:             * <ul>
563:             * 
564:             * <li>has its interrupted status set on entry to this method; or
565:             * 
566:             * <li>is {@link Thread#interrupt interrupted} while acquiring the lock,
567:             * 
568:             * </ul>
569:             * then {@link InterruptedException} is thrown and the current thread's
570:             * interrupted status is cleared.
571:             * If the specified waiting time elapses then the value <tt>false</tt>
572:             * is returned. If the time is
573:             * less than or equal to zero, the method will not wait at all.
574:             * In this implementation, as this method is an explicit interruption
575:             * point, preference is
576:             * given to responding to the interrupt over normal or reentrant
577:             * acquisition of the lock, and over reporting the elapse of the waiting
578:             * time.
579:             *
580:             * @param timeout the time to wait for the lock
581:             * @param unit the time unit of the timeout argument
582:             * @return <tt>true</tt> if the lock was free and was acquired by the
583:             * current thread, or the lock was already held by the current thread; and
584:             * <tt>false</tt> if the waiting time elapsed before the lock could be
585:             * acquired.
586:             * @throws InterruptedException if the current thread is interrupted
587:             * @throws NullPointerException if unit is null
588:             */
589:            public boolean tryLock(long timeout, TimeUnit unit)
590:                    throws InterruptedException {
591:                return sync.tryLock(unit.toNanos(timeout));
592:            }
593:
594:            /**
595:             * Attempts to release this lock. If the current thread is the
596:             * holder of this lock then the hold count is decremented. If the
597:             * hold count is now zero then the lock is released. If the
598:             * current thread is not the holder of this lock then {@link
599:             * IllegalMonitorStateException} is thrown.
600:             *
601:             * @throws IllegalMonitorStateException if the current thread does not
602:             * hold this lock.
603:             */
604:            public void unlock() {
605:                sync.unlock();
606:            }
607:
608:            /**
609:             * Returns a {@link Condition} instance for use with this
610:             * {@link Lock} instance.
611:             * The returned {@link Condition} instance supports the same
612:             * usages as do the {@link Object} monitor methods({@link
613:             * Object#wait() wait}, {@link Object#notify notify}, and {@link
614:             * Object#notifyAll notifyAll}) when used with the built-in monitor lock.
615:             * 
616:             * <ul>
617:             * 
618:             * <li>If this lock is not held when any of the {@link Condition}
619:             * {@link Condition#await() waiting} or {@link Condition#signal
620:             * signalling} methods are called, then an {@link
621:             * IllegalMonitorStateException} is thrown.
622:             * 
623:             * <li>When the condition {@link Condition#await() waiting}
624:             * methods are called the lock is released and, before they
625:             * return, the lock is reacquired and the lock hold count restored
626:             * to what it was when the method was called.
627:             * 
628:             * <li>If a thread is {@link Thread#interrupt interrupted} while
629:             * waiting then the wait will terminate, an {@link
630:             * InterruptedException} will be thrown, and the thread's
631:             * interrupted status will be cleared.
632:             * 
633:             * <li> Waiting threads are signalled in FIFO order
634:             * 
635:             * <li>The ordering of lock reacquisition for threads returning
636:             * from waiting methods is the same as for threads initially
637:             * acquiring the lock, which is in the default case not specified,
638:             * but for <em>fair</em> locks favors those threads that have been
639:             * waiting the longest.
640:             * 
641:             * </ul>
642:             *
643:             * @return the Condition object
644:             */
645:            public Condition newCondition() {
646:                return isFair() ? new FIFOCondVar(this ) : new CondVar(this );
647:            }
648:
649:            /**
650:             * Queries the number of holds on this lock by the current thread.
651:             * A thread has a hold on a lock for each lock action that is not
652:             * matched by an unlock action.
653:             * The hold count information is typically only used for testing and
654:             * debugging purposes. For example, if a certain section of code should
655:             * not be entered with the lock already held then we can assert that fact:
656:             * 
657:             * <pre> class X { ReentrantLock lock = new ReentrantLock(); // ...
658:             * public void m() { assert lock.getHoldCount() == 0; lock.lock(); try {
659:             * // ... method body } finally { lock.unlock(); } } }
660:             * </pre>
661:             *
662:             * @return the number of holds on this lock by the current thread,
663:             * or zero if this lock is not held by the current thread.
664:             */
665:            public int getHoldCount() {
666:                return sync.getHoldCount();
667:            }
668:
669:            /**
670:             * Queries if this lock is held by the current thread.
671:             * Analogous to the {@link Thread#holdsLock} method for built-in
672:             * monitor locks, this method is typically used for debugging and
673:             * testing. For example, a method that should only be called while
674:             * a lock is held can assert that this is the case:
675:             * 
676:             * <pre> class X { ReentrantLock lock = new ReentrantLock(); // ...
677:             * public void m() { assert lock.isHeldByCurrentThread();
678:             * // ... method body } }
679:             * </pre> It can also be used to ensure that a reentrant lock is used
680:             * in a non-reentrant manner, for example:
681:             * 
682:             * <pre> class X { ReentrantLock lock = new ReentrantLock(); // ...
683:             * public void m() { assert !lock.isHeldByCurrentThread(); lock.lock();
684:             * try { // ... method body } finally { lock.unlock(); } } }
685:             * </pre>
686:             *
687:             * @return <tt>true</tt> if current thread holds this lock and
688:             * <tt>false</tt> otherwise.
689:             */
690:            public boolean isHeldByCurrentThread() {
691:                return sync.isHeldByCurrentThread();
692:            }
693:
694:            /**
695:             * Queries if this lock is held by any thread. This method is
696:             * designed for use in monitoring of the system state,
697:             * not for synchronization control.
698:             *
699:             * @return <tt>true</tt> if any thread holds this lock and
700:             * <tt>false</tt> otherwise.
701:             */
702:            public boolean isLocked() {
703:                return sync.isLocked();
704:            }
705:
706:            /**
707:             * Returns true if this lock has fairness set true.
708:             *
709:             * @return true if this lock has fairness set true.
710:             */
711:            public final boolean isFair() {
712:                return sync.isFair();
713:            }
714:
715:            /**
716:             * <tt>null</tt> if not owned. When this method is called by a
717:             * thread that is not the owner, the return value reflects a
718:             * best-effort approximation of current lock status. For example,
719:             * the owner may be momentarily <tt>null</tt> even if there are
720:             * threads trying to acquire the lock but have not yet done so.
721:             * This method is designed to facilitate construction of
722:             * subclasses that provide more extensive lock monitoring facilities.
723:             *
724:             * @return the owner, or <tt>null</tt> if not owned
725:             */
726:            protected Thread getOwner() {
727:                return sync.getOwner();
728:            }
729:
730:            /**
731:             * Queries whether any threads are waiting to acquire this lock. Note that
732:             * because cancellations may occur at any time, a <tt>true</tt>
733:             * return does not guarantee that any other thread will ever
734:             * acquire this lock. This method is designed primarily for use in
735:             * monitoring of the system state.
736:             *
737:             * @return true if there may be other threads waiting to acquire the lock.
738:             */
739:            public final boolean hasQueuedThreads() {
740:                return sync.hasQueuedThreads();
741:            }
742:
743:            /**
744:             * Queries whether the given thread is waiting to acquire this
745:             * lock. Note that because cancellations may occur at any time, a
746:             * <tt>true</tt> return does not guarantee that this thread
747:             * will ever acquire this lock. This method is designed primarily for use
748:             * in monitoring of the system state.
749:             *
750:             * @param thread the thread
751:             * @return true if the given thread is queued waiting for this lock.
752:             * @throws NullPointerException if thread is null
753:             */
754:            public final boolean hasQueuedThread(Thread thread) {
755:                return sync.isQueued(thread);
756:            }
757:
758:            /**
759:             * Returns an estimate of the number of threads waiting to
760:             * acquire this lock. The value is only an estimate because the number of
761:             * threads may change dynamically while this method traverses
762:             * internal data structures. This method is designed for use in
763:             * monitoring of the system state, not for synchronization control.
764:             *
765:             * @return the estimated number of threads waiting for this lock
766:             */
767:            public final int getQueueLength() {
768:                return sync.getQueueLength();
769:            }
770:
771:            /**
772:             * Returns a collection containing threads that may be waiting to
773:             * acquire this lock. Because the actual set of threads may change
774:             * dynamically while constructing this result, the returned
775:             * collection is only a best-effort estimate. The elements of the
776:             * returned collection are in no particular order. This method is
777:             * designed to facilitate construction of subclasses that provide
778:             * more extensive monitoring facilities.
779:             *
780:             * @return the collection of threads
781:             */
782:            protected Collection getQueuedThreads() {
783:                return sync.getQueuedThreads();
784:            }
785:
786:            /**
787:             * Queries whether any threads are waiting on the given condition
788:             * associated with this lock. Note that because timeouts and
789:             * interrupts may occur at any time, a <tt>true</tt> return does
790:             * not guarantee that a future <tt>signal</tt> will awaken any
791:             * threads. This method is designed primarily for use in
792:             * monitoring of the system state.
793:             *
794:             * @param condition the condition
795:             * @return <tt>true</tt> if there are any waiting threads.
796:             * @throws IllegalMonitorStateException if this lock is not held
797:             * @throws IllegalArgumentException if the given condition is
798:             * not associated with this lock
799:             * @throws NullPointerException if condition null
800:             */
801:            public boolean hasWaiters(Condition condition) {
802:                return asCondVar(condition).hasWaiters();
803:            }
804:
805:            /**
806:             * Returns an estimate of the number of threads waiting on the
807:             * given condition associated with this lock. Note that because
808:             * timeouts and interrupts may occur at any time, the estimate
809:             * serves only as an upper bound on the actual number of waiters.
810:             * This method is designed for use in monitoring of the system
811:             * state, not for synchronization control.
812:             *
813:             * @param condition the condition
814:             * @return the estimated number of waiting threads.
815:             * @throws IllegalMonitorStateException if this lock is not held
816:             * @throws IllegalArgumentException if the given condition is
817:             * not associated with this lock
818:             * @throws NullPointerException if condition null
819:             */
820:            public int getWaitQueueLength(Condition condition) {
821:                return asCondVar(condition).getWaitQueueLength();
822:            }
823:
824:            /**
825:             * Returns a collection containing those threads that may be
826:             * waiting on the given condition associated with this lock.
827:             * Because the actual set of threads may change dynamically while
828:             * constructing this result, the returned collection is only a
829:             * best-effort estimate. The elements of the returned collection
830:             * are in no particular order. This method is designed to
831:             * facilitate construction of subclasses that provide more
832:             * extensive condition monitoring facilities.
833:             *
834:             * @param condition the condition
835:             * @return the collection of threads
836:             * @throws IllegalMonitorStateException if this lock is not held
837:             * @throws IllegalArgumentException if the given condition is
838:             * not associated with this lock
839:             * @throws NullPointerException if condition null
840:             */
841:            protected Collection getWaitingThreads(Condition condition) {
842:                return asCondVar(condition).getWaitingThreads();
843:            }
844:
845:            /**
846:             * Returns a string identifying this lock, as well as its lock
847:             * state. The state, in brackets, includes either the String
848:             * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
849:             * followed by the {@link Thread#getName} of the owning thread.
850:             *
851:             * @return a string identifying this lock, as well as its lock state.
852:             */
853:            public String toString() {
854:                Thread o = getOwner();
855:                return super .toString()
856:                        + ((o == null) ? "[Unlocked]" : "[Locked by thread "
857:                                + o.getName() + "]");
858:            }
859:
860:            private CondVar asCondVar(Condition condition) {
861:                if (condition == null)
862:                    throw new NullPointerException();
863:                if (!(condition instanceof  CondVar))
864:                    throw new IllegalArgumentException("not owner");
865:                CondVar condVar = (CondVar) condition;
866:                if (condVar.lock != this )
867:                    throw new IllegalArgumentException("not owner");
868:                return condVar;
869:            }
870:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.