Source Code Cross Referenced for ReentrantReadWriteLock.java in  » Apache-Harmony-Java-SE » java-package » java » util » concurrent » locks » 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 » Apache Harmony Java SE » java package » java.util.concurrent.locks 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Written by Doug Lea with assistance from members of JCP JSR-166
0003:         * Expert Group and released to the public domain, as explained at
0004:         * http://creativecommons.org/licenses/publicdomain
0005:         */
0006:
0007:        package java.util.concurrent.locks;
0008:
0009:        import java.util.concurrent.*;
0010:        import java.util.concurrent.atomic.*;
0011:        import java.util.*;
0012:
0013:        /**
0014:         * An implementation of {@link ReadWriteLock} supporting similar
0015:         * semantics to {@link ReentrantLock}.
0016:         * <p>This class has the following properties:
0017:         *
0018:         * <ul>
0019:         * <li><b>Acquisition order</b>
0020:         *
0021:         * <p> This class does not impose a reader or writer preference
0022:         * ordering for lock access.  However, it does support an optional
0023:         * <em>fairness</em> policy.  When constructed as fair, threads
0024:         * contend for entry using an approximately arrival-order policy. When
0025:         * the write lock is released either the longest-waiting single writer
0026:         * will be assigned the write lock, or if there is a reader waiting
0027:         * longer than any writer, the set of readers will be assigned the
0028:         * read lock.  When constructed as non-fair, the order of entry to the
0029:         * lock need not be in arrival order.  In either case, if readers are
0030:         * active and a writer enters the lock then no subsequent readers will
0031:         * be granted the read lock until after that writer has acquired and
0032:         * released the write lock.
0033:         * 
0034:         * <li><b>Reentrancy</b>
0035:         * <p>This lock allows both readers and writers to reacquire read or
0036:         * write locks in the style of a {@link ReentrantLock}. Readers are not
0037:         * allowed until all write locks held by the writing thread have been
0038:         * released.  
0039:         * <p>Additionally, a writer can acquire the read lock - but not vice-versa.
0040:         * Among other applications, reentrancy can be useful when
0041:         * write locks are held during calls or callbacks to methods that
0042:         * perform reads under read locks. 
0043:         * If a reader tries to acquire the write lock it will never succeed.
0044:         * 
0045:         * <li><b>Lock downgrading</b>
0046:         * <p>Reentrancy also allows downgrading from the write lock to a read lock,
0047:         * by acquiring the write lock, then the read lock and then releasing the
0048:         * write lock. However, upgrading from a read lock to the write lock, is
0049:         * <b>not</b> possible.
0050:         *
0051:         * <li><b>Interruption of lock acquisition</b>
0052:         * <p>The read lock and write lock both support interruption during lock
0053:         * acquisition.
0054:         *
0055:         * <li><b>{@link Condition} support</b>
0056:         * <p>The write lock provides a {@link Condition} implementation that
0057:         * behaves in the same way, with respect to the write lock, as the 
0058:         * {@link Condition} implementation provided by
0059:         * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
0060:         * This {@link Condition} can, of course, only be used with the write lock.
0061:         * <p>The read lock does not support a {@link Condition} and
0062:         * <tt>readLock().newCondition()</tt> throws 
0063:         * <tt>UnsupportedOperationException</tt>.
0064:         *
0065:         * <li><b>Instrumentation</b>
0066:         * <P> This class supports methods to determine whether locks
0067:         * are held or contended. These methods are designed for monitoring
0068:         * system state, not for synchronization control.
0069:         * </ul>
0070:         *
0071:         * <p> Serialization of this class behaves in the same way as built-in
0072:         * locks: a deserialized lock is in the unlocked state, regardless of
0073:         * its state when serialized.
0074:         *
0075:         * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit
0076:         * reentrancy to perform lock downgrading after updating a cache (exception
0077:         * handling is elided for simplicity):
0078:         * <pre>
0079:         * class CachedData {
0080:         *   Object data;
0081:         *   volatile boolean cacheValid;
0082:         *   ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
0083:         *
0084:         *   void processCachedData() {
0085:         *     rwl.readLock().lock();
0086:         *     if (!cacheValid) {
0087:         *        // upgrade lock manually
0088:         *        rwl.readLock().unlock();   // must unlock first to obtain writelock
0089:         *        rwl.writeLock().lock();
0090:         *        if (!cacheValid) { // recheck
0091:         *          data = ...
0092:         *          cacheValid = true;
0093:         *        }
0094:         *        // downgrade lock
0095:         *        rwl.readLock().lock();  // reacquire read without giving up write lock
0096:         *        rwl.writeLock().unlock(); // unlock write, still hold read
0097:         *     }
0098:         *
0099:         *     use(data);
0100:         *     rwl.readLock().unlock();
0101:         *   }
0102:         * }
0103:         * </pre>
0104:         *
0105:         * ReentrantReadWriteLocks can be used to improve concurrency in some
0106:         * uses of some kinds of Collections. This is typically worthwhile
0107:         * only when the collections are expected to be large, accessed by
0108:         * more reader threads than writer threads, and entail operations with
0109:         * overhead that outweighs synchronization overhead. For example, here
0110:         * is a class using a TreeMap that is expected to be large and 
0111:         * concurrently accessed.
0112:         *
0113:         * <pre>
0114:         * class RWDictionary {
0115:         *    private final Map&lt;String, Data&gt;  m = new TreeMap&lt;String, Data&gt;();
0116:         *    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
0117:         *    private final Lock r = rwl.readLock();
0118:         *    private final Lock w = rwl.writeLock();
0119:         *
0120:         *    public Data get(String key) {
0121:         *        r.lock(); try { return m.get(key); } finally { r.unlock(); }
0122:         *    }
0123:         *    public String[] allKeys() {
0124:         *        r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
0125:         *    }
0126:         *    public Data put(String key, Data value) {
0127:         *        w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
0128:         *    }
0129:         *    public void clear() {
0130:         *        w.lock(); try { m.clear(); } finally { w.unlock(); }
0131:         *    }
0132:         * }
0133:         * </pre>
0134:         * 
0135:         *
0136:         * <h3>Implementation Notes</h3>
0137:         *
0138:         * <p>A reentrant write lock intrinsically defines an owner and can
0139:         * only be released by the thread that acquired it.  In contrast, in
0140:         * this implementation, the read lock has no concept of ownership, and
0141:         * there is no requirement that the thread releasing a read lock is
0142:         * the same as the one that acquired it.  However, this property is
0143:         * not guaranteed to hold in future implementations of this class.
0144:         *
0145:         * <p> This lock supports a maximum of 65536 recursive write locks
0146:         * and 65536 read locks. Attempts to exceed these limits result in
0147:         * {@link Error} throws from locking methods.
0148:         *
0149:         * @since 1.5
0150:         * @author Doug Lea
0151:         *
0152:         */
0153:        public class ReentrantReadWriteLock implements  ReadWriteLock,
0154:                java.io.Serializable {
0155:            private static final long serialVersionUID = -6992448646407690164L;
0156:            /** Inner class providing readlock */
0157:            private final ReentrantReadWriteLock.ReadLock readerLock;
0158:            /** Inner class providing writelock */
0159:            private final ReentrantReadWriteLock.WriteLock writerLock;
0160:            /** Performs all synchronization mechanics */
0161:            private final Sync sync;
0162:
0163:            /**
0164:             * Creates a new <tt>ReentrantReadWriteLock</tt> with
0165:             * default ordering properties.
0166:             */
0167:            public ReentrantReadWriteLock() {
0168:                sync = new NonfairSync();
0169:                readerLock = new ReadLock(this );
0170:                writerLock = new WriteLock(this );
0171:            }
0172:
0173:            /**
0174:             * Creates a new <tt>ReentrantReadWriteLock</tt> with
0175:             * the given fairness policy.
0176:             *
0177:             * @param fair true if this lock should use a fair ordering policy
0178:             */
0179:            public ReentrantReadWriteLock(boolean fair) {
0180:                sync = (fair) ? new FairSync() : new NonfairSync();
0181:                readerLock = new ReadLock(this );
0182:                writerLock = new WriteLock(this );
0183:            }
0184:
0185:            public ReentrantReadWriteLock.WriteLock writeLock() {
0186:                return writerLock;
0187:            }
0188:
0189:            public ReentrantReadWriteLock.ReadLock readLock() {
0190:                return readerLock;
0191:            }
0192:
0193:            /* 
0194:             * Read vs write count extraction constants and functions.
0195:             * Lock state is logically divided into two shorts: The lower
0196:             * one representing the exclusive (writer) lock hold count,
0197:             * and the upper the shared (reader) hold count.
0198:             */
0199:
0200:            static final int SHARED_SHIFT = 16;
0201:            static final int SHARED_UNIT = (1 << SHARED_SHIFT);
0202:            static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
0203:
0204:            /** Returns the number of shared holds represented in count  */
0205:            static int sharedCount(int c) {
0206:                return c >>> SHARED_SHIFT;
0207:            }
0208:
0209:            /** Returns the number of exclusive holds represented in count  */
0210:            static int exclusiveCount(int c) {
0211:                return c & EXCLUSIVE_MASK;
0212:            }
0213:
0214:            /** 
0215:             * Synchronization implementation for ReentrantReadWriteLock.
0216:             * Subclassed into fair and nonfair versions.
0217:             */
0218:            abstract static class Sync extends AbstractQueuedSynchronizer {
0219:                /** Current (exclusive) owner thread */
0220:                transient Thread owner;
0221:
0222:                /**
0223:                 * Perform write lock. Allows fast path in non-fair version.
0224:                 */
0225:                abstract void wlock();
0226:
0227:                /** 
0228:                 * Perform non-fair tryLock for write.  tryAcquire is
0229:                 * implemented in subclasses, but both versions need nonfair
0230:                 * try for trylock method
0231:                 */
0232:                final boolean nonfairTryAcquire(int acquires) {
0233:                    // mask out readlocks if called from condition methods
0234:                    acquires = exclusiveCount(acquires);
0235:                    Thread current = Thread.currentThread();
0236:                    int c = getState();
0237:                    int w = exclusiveCount(c);
0238:                    if (w + acquires >= SHARED_UNIT)
0239:                        throw new Error("Maximum lock count exceeded");
0240:                    if (c != 0 && (w == 0 || current != owner))
0241:                        return false;
0242:                    if (!compareAndSetState(c, c + acquires))
0243:                        return false;
0244:                    owner = current;
0245:                    return true;
0246:                }
0247:
0248:                /** 
0249:                 * Perform nonfair tryLock for read. 
0250:                 */
0251:                final int nonfairTryAcquireShared(int acquires) {
0252:                    for (;;) {
0253:                        int c = getState();
0254:                        int nextc = c + (acquires << SHARED_SHIFT);
0255:                        if (nextc < c)
0256:                            throw new Error("Maximum lock count exceeded");
0257:                        if (exclusiveCount(c) != 0
0258:                                && owner != Thread.currentThread())
0259:                            return -1;
0260:                        if (compareAndSetState(c, nextc))
0261:                            return 1;
0262:                        // Recheck count if lost CAS
0263:                    }
0264:                }
0265:
0266:                protected final boolean tryRelease(int releases) {
0267:                    Thread current = Thread.currentThread();
0268:                    int c = getState();
0269:                    if (owner != current)
0270:                        throw new IllegalMonitorStateException();
0271:                    int nextc = c - releases;
0272:                    boolean free = false;
0273:                    if (exclusiveCount(c) == releases) {
0274:                        free = true;
0275:                        owner = null;
0276:                    }
0277:                    setState(nextc);
0278:                    return free;
0279:                }
0280:
0281:                protected final boolean tryReleaseShared(int releases) {
0282:                    for (;;) {
0283:                        int c = getState();
0284:                        int nextc = c - (releases << SHARED_SHIFT);
0285:                        if (nextc < 0)
0286:                            throw new IllegalMonitorStateException();
0287:                        if (compareAndSetState(c, nextc))
0288:                            return nextc == 0;
0289:                    }
0290:                }
0291:
0292:                protected final boolean isHeldExclusively() {
0293:                    return exclusiveCount(getState()) != 0
0294:                            && owner == Thread.currentThread();
0295:                }
0296:
0297:                // Methods relayed to outer class
0298:
0299:                final ConditionObject newCondition() {
0300:                    return new ConditionObject();
0301:                }
0302:
0303:                final Thread getOwner() {
0304:                    int c = exclusiveCount(getState());
0305:                    Thread o = owner;
0306:                    return (c == 0) ? null : o;
0307:                }
0308:
0309:                final int getReadLockCount() {
0310:                    return sharedCount(getState());
0311:                }
0312:
0313:                final boolean isWriteLocked() {
0314:                    return exclusiveCount(getState()) != 0;
0315:                }
0316:
0317:                final int getWriteHoldCount() {
0318:                    int c = exclusiveCount(getState());
0319:                    Thread o = owner;
0320:                    return (o == Thread.currentThread()) ? c : 0;
0321:                }
0322:
0323:                /**
0324:                 * Reconstitute this lock instance from a stream
0325:                 * @param s the stream
0326:                 */
0327:                private void readObject(java.io.ObjectInputStream s)
0328:                        throws java.io.IOException, ClassNotFoundException {
0329:                    s.defaultReadObject();
0330:                    setState(0); // reset to unlocked state
0331:                }
0332:
0333:                final int getCount() {
0334:                    return getState();
0335:                }
0336:            }
0337:
0338:            /** 
0339:             * Nonfair version of Sync
0340:             */
0341:            final static class NonfairSync extends Sync {
0342:                protected final boolean tryAcquire(int acquires) {
0343:                    return nonfairTryAcquire(acquires);
0344:                }
0345:
0346:                protected final int tryAcquireShared(int acquires) {
0347:                    return nonfairTryAcquireShared(acquires);
0348:                }
0349:
0350:                // Use fastpath for main write lock method
0351:                final void wlock() {
0352:                    if (compareAndSetState(0, 1))
0353:                        owner = Thread.currentThread();
0354:                    else
0355:                        acquire(1);
0356:                }
0357:            }
0358:
0359:            /** 
0360:             * Fair version of Sync
0361:             */
0362:            final static class FairSync extends Sync {
0363:                protected final boolean tryAcquire(int acquires) {
0364:                    // mask out readlocks if called from condition methods
0365:                    acquires = exclusiveCount(acquires);
0366:                    Thread current = Thread.currentThread();
0367:                    Thread first;
0368:                    int c = getState();
0369:                    int w = exclusiveCount(c);
0370:                    if (w + acquires >= SHARED_UNIT)
0371:                        throw new Error("Maximum lock count exceeded");
0372:                    if ((w == 0 || current != owner)
0373:                            && (c != 0 || ((first = getFirstQueuedThread()) != null && first != current)))
0374:                        return false;
0375:                    if (!compareAndSetState(c, c + acquires))
0376:                        return false;
0377:                    owner = current;
0378:                    return true;
0379:                }
0380:
0381:                protected final int tryAcquireShared(int acquires) {
0382:                    Thread current = Thread.currentThread();
0383:                    for (;;) {
0384:                        Thread first = getFirstQueuedThread();
0385:                        if (first != null && first != current)
0386:                            return -1;
0387:                        int c = getState();
0388:                        int nextc = c + (acquires << SHARED_SHIFT);
0389:                        if (nextc < c)
0390:                            throw new Error("Maximum lock count exceeded");
0391:                        if (exclusiveCount(c) != 0
0392:                                && owner != Thread.currentThread())
0393:                            return -1;
0394:                        if (compareAndSetState(c, nextc))
0395:                            return 1;
0396:                        // Recheck count if lost CAS
0397:                    }
0398:                }
0399:
0400:                final void wlock() { // no fast path
0401:                    acquire(1);
0402:                }
0403:            }
0404:
0405:            /**
0406:             * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
0407:             */
0408:            public static class ReadLock implements  Lock, java.io.Serializable {
0409:                private static final long serialVersionUID = -5992448646407690164L;
0410:                private final Sync sync;
0411:
0412:                /** 
0413:                 * Constructor for use by subclasses 
0414:                 * @param lock the outer lock object
0415:                 * @throws NullPointerException if lock null
0416:                 */
0417:                protected ReadLock(ReentrantReadWriteLock lock) {
0418:                    sync = lock.sync;
0419:                }
0420:
0421:                /**
0422:                 * Acquires the shared lock. 
0423:                 *
0424:                 * <p>Acquires the lock if it is not held exclusively by
0425:                 * another thread and returns immediately.
0426:                 *
0427:                 * <p>If the lock is held exclusively by another thread then
0428:                 * the current thread becomes disabled for thread scheduling
0429:                 * purposes and lies dormant until the lock has been acquired.
0430:                 */
0431:                public void lock() {
0432:                    sync.acquireShared(1);
0433:                }
0434:
0435:                /**
0436:                 * Acquires the shared lock unless the current thread is 
0437:                 * {@link Thread#interrupt interrupted}.
0438:                 *
0439:                 * <p>Acquires the shared lock if it is not held exclusively
0440:                 * by another thread and returns immediately.
0441:                 *
0442:                 * <p>If the lock is held by another thread then the
0443:                 * current thread becomes disabled for thread scheduling 
0444:                 * purposes and lies dormant until one of two things happens:
0445:                 *
0446:                 * <ul>
0447:                 *
0448:                 * <li>The lock is acquired by the current thread; or
0449:                 *
0450:                 * <li>Some other thread {@link Thread#interrupt interrupts}
0451:                 * the current thread.
0452:                 *
0453:                 * </ul>
0454:                 *
0455:                 * <p>If the current thread:
0456:                 *
0457:                 * <ul>
0458:                 *
0459:                 * <li>has its interrupted status set on entry to this method; or 
0460:                 *
0461:                 * <li>is {@link Thread#interrupt interrupted} while acquiring 
0462:                 * the lock,
0463:                 *
0464:                 * </ul>
0465:                 *
0466:                 * then {@link InterruptedException} is thrown and the current
0467:                 * thread's interrupted status is cleared.
0468:                 *
0469:                 * <p>In this implementation, as this method is an explicit
0470:                 * interruption point, preference is given to responding to
0471:                 * the interrupt over normal or reentrant acquisition of the
0472:                 * lock.
0473:                 *
0474:                 * @throws InterruptedException if the current thread is interrupted
0475:                 */
0476:                public void lockInterruptibly() throws InterruptedException {
0477:                    sync.acquireSharedInterruptibly(1);
0478:                }
0479:
0480:                /**
0481:                 * Acquires the shared lock only if it is not held exclusively by
0482:                 * another thread at the time of invocation.
0483:                 *
0484:                 * <p>Acquires the lock if it is not held exclusively by
0485:                 * another thread and returns immediately with the value
0486:                 * <tt>true</tt>. Even when this lock has been set to use a
0487:                 * fair ordering policy, a call to <tt>tryLock()</tt>
0488:                 * <em>will</em> immediately acquire the lock if it is
0489:                 * available, whether or not other threads are currently
0490:                 * waiting for the lock.  This &quot;barging&quot; behavior
0491:                 * can be useful in certain circumstances, even though it
0492:                 * breaks fairness. If you want to honor the fairness setting
0493:                 * for this lock, then use {@link #tryLock(long, TimeUnit)
0494:                 * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
0495:                 * (it also detects interruption).
0496:                 *
0497:                 * <p>If the lock is held exclusively by another thread then
0498:                 * this method will return immediately with the value
0499:                 * <tt>false</tt>.
0500:                 *
0501:                 * @return <tt>true</tt> if the lock was acquired.
0502:                 */
0503:                public boolean tryLock() {
0504:                    return sync.nonfairTryAcquireShared(1) >= 0;
0505:                }
0506:
0507:                /**
0508:                 * Acquires the shared lock if it is not held exclusively by
0509:                 * another thread within the given waiting time and the
0510:                 * current thread has not been {@link Thread#interrupt
0511:                 * interrupted}.
0512:                 *
0513:                 * <p>Acquires the lock if it is not held exclusively by
0514:                 * another thread and returns immediately with the value
0515:                 * <tt>true</tt>. If this lock has been set to use a fair
0516:                 * ordering policy then an available lock <em>will not</em> be
0517:                 * acquired if any other threads are waiting for the
0518:                 * lock. This is in contrast to the {@link #tryLock()}
0519:                 * method. If you want a timed <tt>tryLock</tt> that does
0520:                 * permit barging on a fair lock then combine the timed and
0521:                 * un-timed forms together:
0522:                 *
0523:                 * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
0524:                 * </pre>
0525:                 *
0526:                 * <p>If the lock is held exclusively by another thread then the
0527:                 * current thread becomes disabled for thread scheduling 
0528:                 * purposes and lies dormant until one of three things happens:
0529:                 *
0530:                 * <ul>
0531:                 *
0532:                 * <li>The lock is acquired by the current thread; or
0533:                 *
0534:                 * <li>Some other thread {@link Thread#interrupt interrupts} the current
0535:                 * thread; or
0536:                 *
0537:                 * <li>The specified waiting time elapses
0538:                 *
0539:                 * </ul>
0540:                 *
0541:                 * <p>If the lock is acquired then the value <tt>true</tt> is
0542:                 * returned.
0543:                 *
0544:                 * <p>If the current thread:
0545:                 *
0546:                 * <ul>
0547:                 *
0548:                 * <li>has its interrupted status set on entry to this method; or 
0549:                 *
0550:                 * <li>is {@link Thread#interrupt interrupted} while acquiring
0551:                 * the lock,
0552:                 *
0553:                 * </ul> then {@link InterruptedException} is thrown and the
0554:                 * current thread's interrupted status is cleared.
0555:                 *
0556:                 * <p>If the specified waiting time elapses then the value
0557:                 * <tt>false</tt> is returned.  If the time is less than or
0558:                 * equal to zero, the method will not wait at all.
0559:                 *
0560:                 * <p>In this implementation, as this method is an explicit
0561:                 * interruption point, preference is given to responding to
0562:                 * the interrupt over normal or reentrant acquisition of the
0563:                 * lock, and over reporting the elapse of the waiting time.
0564:                 *
0565:                 * @param timeout the time to wait for the lock
0566:                 * @param unit the time unit of the timeout argument
0567:                 *
0568:                 * @return <tt>true</tt> if the lock was acquired.
0569:                 *
0570:                 * @throws InterruptedException if the current thread is interrupted
0571:                 * @throws NullPointerException if unit is null
0572:                 *
0573:                 */
0574:                public boolean tryLock(long timeout, TimeUnit unit)
0575:                        throws InterruptedException {
0576:                    return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
0577:                }
0578:
0579:                /**
0580:                 * Attempts to release this lock.  
0581:                 *
0582:                 * <p> If the number of readers is now zero then the lock
0583:                 * is made available for other lock attempts.
0584:                 */
0585:                public void unlock() {
0586:                    sync.releaseShared(1);
0587:                }
0588:
0589:                /**
0590:                 * Throws UnsupportedOperationException because ReadLocks
0591:                 * do not support conditions.
0592:                 * @throws UnsupportedOperationException always
0593:                 */
0594:                public Condition newCondition() {
0595:                    throw new UnsupportedOperationException();
0596:                }
0597:
0598:                /**
0599:                 * Returns a string identifying this lock, as well as its lock state.
0600:                 * The state, in brackets, includes the String 
0601:                 * &quot;Read locks =&quot; followed by the number of held
0602:                 * read locks.
0603:                 * @return a string identifying this lock, as well as its lock state.
0604:                 */
0605:                public String toString() {
0606:                    int r = sync.getReadLockCount();
0607:                    return super .toString() + "[Read locks = " + r + "]";
0608:                }
0609:
0610:            }
0611:
0612:            /**
0613:             * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
0614:             */
0615:            public static class WriteLock implements  Lock, java.io.Serializable {
0616:                private static final long serialVersionUID = -4992448646407690164L;
0617:                private final Sync sync;
0618:
0619:                /** 
0620:                 * Constructor for use by subclasses 
0621:                 * @param lock the outer lock object
0622:                 * @throws NullPointerException if lock null
0623:                 */
0624:                protected WriteLock(ReentrantReadWriteLock lock) {
0625:                    sync = lock.sync;
0626:                }
0627:
0628:                /**
0629:                 * Acquire the lock. 
0630:                 *
0631:                 * <p>Acquires the lock if it is not held by another thread
0632:                 * and returns immediately, setting the lock hold count to
0633:                 * one.
0634:                 *
0635:                 * <p>If the current thread already holds the lock then the
0636:                 * hold count is incremented by one and the method returns
0637:                 * immediately.
0638:                 *
0639:                 * <p>If the lock is held by another thread then the current
0640:                 * thread becomes disabled for thread scheduling purposes and
0641:                 * lies dormant until the lock has been acquired, at which
0642:                 * time the lock hold count is set to one.
0643:                 */
0644:                public void lock() {
0645:                    sync.wlock();
0646:                }
0647:
0648:                /**
0649:                 * Acquires the lock unless the current thread is {@link
0650:                 * Thread#interrupt interrupted}.
0651:                 *
0652:                 * <p>Acquires the lock if it is not held by another thread
0653:                 * and returns immediately, setting the lock hold count to
0654:                 * one.
0655:                 *
0656:                 * <p>If the current thread already holds this lock then the
0657:                 * hold count is incremented by one and the method returns
0658:                 * immediately.
0659:                 *
0660:                 * <p>If the lock is held by another thread then the current
0661:                 * thread becomes disabled for thread scheduling purposes and
0662:                 * lies dormant until one of two things happens:
0663:                 *
0664:                 * <ul>
0665:                 *
0666:                 * <li>The lock is acquired by the current thread; or
0667:                 *
0668:                 * <li>Some other thread {@link Thread#interrupt interrupts}
0669:                 * the current thread.
0670:                 *
0671:                 * </ul>
0672:                 *
0673:                 * <p>If the lock is acquired by the current thread then the
0674:                 * lock hold count is set to one.
0675:                 *
0676:                 * <p>If the current thread:
0677:                 *
0678:                 * <ul>
0679:                 *
0680:                 * <li>has its interrupted status set on entry to this method;
0681:                 * or
0682:                 *
0683:                 * <li>is {@link Thread#interrupt interrupted} while acquiring
0684:                 * the lock,
0685:                 *
0686:                 * </ul>
0687:                 *
0688:                 * then {@link InterruptedException} is thrown and the current
0689:                 * thread's interrupted status is cleared.
0690:                 *
0691:                 * <p>In this implementation, as this method is an explicit
0692:                 * interruption point, preference is given to responding to
0693:                 * the interrupt over normal or reentrant acquisition of the
0694:                 * lock.
0695:                 *
0696:                 * @throws InterruptedException if the current thread is interrupted
0697:                 */
0698:                public void lockInterruptibly() throws InterruptedException {
0699:                    sync.acquireInterruptibly(1);
0700:                }
0701:
0702:                /**
0703:                 * Acquires the lock only if it is not held by another thread
0704:                 * at the time of invocation.
0705:                 *
0706:                 * <p>Acquires the lock if it is not held by another thread
0707:                 * and returns immediately with the value <tt>true</tt>,
0708:                 * setting the lock hold count to one. Even when this lock has
0709:                 * been set to use a fair ordering policy, a call to
0710:                 * <tt>tryLock()</tt> <em>will</em> immediately acquire the
0711:                 * lock if it is available, whether or not other threads are
0712:                 * currently waiting for the lock.  This &quot;barging&quot;
0713:                 * behavior can be useful in certain circumstances, even
0714:                 * though it breaks fairness. If you want to honor the
0715:                 * fairness setting for this lock, then use {@link
0716:                 * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
0717:                 * which is almost equivalent (it also detects interruption).
0718:                 *
0719:                 * <p> If the current thread already holds this lock then the
0720:                 * hold count is incremented by one and the method returns
0721:                 * <tt>true</tt>.
0722:                 *
0723:                 * <p>If the lock is held by another thread then this method
0724:                 * will return immediately with the value <tt>false</tt>.
0725:                 *
0726:                 * @return <tt>true</tt> if the lock was free and was acquired by the
0727:                 * current thread, or the lock was already held by the current thread; and
0728:                 * <tt>false</tt> otherwise.
0729:                 */
0730:                public boolean tryLock() {
0731:                    return sync.nonfairTryAcquire(1);
0732:                }
0733:
0734:                /**
0735:                 * Acquires the lock if it is not held by another thread
0736:                 * within the given waiting time and the current thread has
0737:                 * not been {@link Thread#interrupt interrupted}.
0738:                 *
0739:                 * <p>Acquires the lock if it is not held by another thread
0740:                 * and returns immediately with the value <tt>true</tt>,
0741:                 * setting the lock hold count to one. If this lock has been
0742:                 * set to use a fair ordering policy then an available lock
0743:                 * <em>will not</em> be acquired if any other threads are
0744:                 * waiting for the lock. This is in contrast to the {@link
0745:                 * #tryLock()} method. If you want a timed <tt>tryLock</tt>
0746:                 * that does permit barging on a fair lock then combine the
0747:                 * timed and un-timed forms together:
0748:                 *
0749:                 * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
0750:                 * </pre>
0751:                 *
0752:                 * <p>If the current thread already holds this lock then the
0753:                 * hold count is incremented by one and the method returns
0754:                 * <tt>true</tt>.
0755:                 *
0756:                 * <p>If the lock is held by another thread then the current
0757:                 * thread becomes disabled for thread scheduling purposes and
0758:                 * lies dormant until one of three things happens:
0759:                 *
0760:                 * <ul>
0761:                 *
0762:                 * <li>The lock is acquired by the current thread; or
0763:                 *
0764:                 * <li>Some other thread {@link Thread#interrupt interrupts}
0765:                 * the current thread; or
0766:                 *
0767:                 * <li>The specified waiting time elapses
0768:                 *
0769:                 * </ul>
0770:                 *
0771:                 * <p>If the lock is acquired then the value <tt>true</tt> is
0772:                 * returned and the lock hold count is set to one.
0773:                 *
0774:                 * <p>If the current thread:
0775:                 *
0776:                 * <ul>
0777:                 *
0778:                 * <li>has its interrupted status set on entry to this method;
0779:                 * or
0780:                 *
0781:                 * <li>is {@link Thread#interrupt interrupted} while acquiring
0782:                 * the lock,
0783:                 *
0784:                 * </ul> 
0785:                 *
0786:                 * then {@link InterruptedException} is thrown and the current
0787:                 * thread's interrupted status is cleared.
0788:                 *
0789:                 * <p>If the specified waiting time elapses then the value
0790:                 * <tt>false</tt> is returned.  If the time is less than or
0791:                 * equal to zero, the method will not wait at all.
0792:                 *
0793:                 * <p>In this implementation, as this method is an explicit
0794:                 * interruption point, preference is given to responding to
0795:                 * the interrupt over normal or reentrant acquisition of the
0796:                 * lock, and over reporting the elapse of the waiting time.
0797:                 *
0798:                 * @param timeout the time to wait for the lock
0799:                 * @param unit the time unit of the timeout argument
0800:                 *
0801:                 * @return <tt>true</tt> if the lock was free and was acquired
0802:                 * by the current thread, or the lock was already held by the
0803:                 * current thread; and <tt>false</tt> if the waiting time
0804:                 * elapsed before the lock could be acquired.
0805:                 *
0806:                 * @throws InterruptedException if the current thread is interrupted
0807:                 * @throws NullPointerException if unit is null
0808:                 *
0809:                 */
0810:                public boolean tryLock(long timeout, TimeUnit unit)
0811:                        throws InterruptedException {
0812:                    return sync.tryAcquireNanos(1, unit.toNanos(timeout));
0813:                }
0814:
0815:                /**
0816:                 * Attempts to release this lock.  
0817:                 *
0818:                 * <p>If the current thread is the holder of this lock then
0819:                 * the hold count is decremented. If the hold count is now
0820:                 * zero then the lock is released.  If the current thread is
0821:                 * not the holder of this lock then {@link
0822:                 * IllegalMonitorStateException} is thrown.
0823:                 * @throws IllegalMonitorStateException if the current thread does not
0824:                 * hold this lock.
0825:                 */
0826:                public void unlock() {
0827:                    sync.release(1);
0828:                }
0829:
0830:                /**
0831:                 * Returns a {@link Condition} instance for use with this
0832:                 * {@link Lock} instance. 
0833:                 * <p>The returned {@link Condition} instance supports the same
0834:                 * usages as do the {@link Object} monitor methods ({@link
0835:                 * Object#wait() wait}, {@link Object#notify notify}, and {@link
0836:                 * Object#notifyAll notifyAll}) when used with the built-in
0837:                 * monitor lock.
0838:                 *
0839:                 * <ul>
0840:                 *
0841:                 * <li>If this write lock is not held when any {@link
0842:                 * Condition} method is called then an {@link
0843:                 * IllegalMonitorStateException} is thrown.  (Read locks are
0844:                 * held independently of write locks, so are not checked or
0845:                 * affected. However it is essentially always an error to
0846:                 * invoke a condition waiting method when the current thread
0847:                 * has also acquired read locks, since other threads that
0848:                 * could unblock it will not be able to access the write
0849:                 * lock.)
0850:                 *
0851:                 * <li>When the condition {@link Condition#await() waiting}
0852:                 * methods are called the write lock is released and, before
0853:                 * they return, the write lock is reacquired and the lock hold
0854:                 * count restored to what it was when the method was called.
0855:                 *
0856:                 * <li>If a thread is {@link Thread#interrupt interrupted} while
0857:                 * waiting then the wait will terminate, an {@link
0858:                 * InterruptedException} will be thrown, and the thread's
0859:                 * interrupted status will be cleared.
0860:                 *
0861:                 * <li> Waiting threads are signalled in FIFO order
0862:                 *
0863:                 * <li>The ordering of lock reacquisition for threads returning
0864:                 * from waiting methods is the same as for threads initially
0865:                 * acquiring the lock, which is in the default case not specified,
0866:                 * but for <em>fair</em> locks favors those threads that have been
0867:                 * waiting the longest.
0868:                 * 
0869:                 * </ul>
0870:                 * @return the Condition object
0871:                 */
0872:                public Condition newCondition() {
0873:                    return sync.newCondition();
0874:                }
0875:
0876:                /**
0877:                 * Returns a string identifying this lock, as well as its lock
0878:                 * state.  The state, in brackets includes either the String
0879:                 * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
0880:                 * followed by the {@link Thread#getName} of the owning thread.
0881:                 * @return a string identifying this lock, as well as its lock state.
0882:                 */
0883:                public String toString() {
0884:                    Thread owner = sync.getOwner();
0885:                    return super .toString()
0886:                            + ((owner == null) ? "[Unlocked]"
0887:                                    : "[Locked by thread " + owner.getName()
0888:                                            + "]");
0889:                }
0890:
0891:            }
0892:
0893:            // Instrumentation and status
0894:
0895:            /**
0896:             * Returns true if this lock has fairness set true.
0897:             * @return true if this lock has fairness set true.
0898:             */
0899:            public final boolean isFair() {
0900:                return sync instanceof  FairSync;
0901:            }
0902:
0903:            /**
0904:             * Returns the thread that currently owns the exclusive lock, or
0905:             * <tt>null</tt> if not owned. Note that the owner may be
0906:             * momentarily <tt>null</tt> even if there are threads trying to
0907:             * acquire the lock but have not yet done so.  This method is
0908:             * designed to facilitate construction of subclasses that provide
0909:             * more extensive lock monitoring facilities.
0910:             * @return the owner, or <tt>null</tt> if not owned.
0911:             */
0912:            protected Thread getOwner() {
0913:                return sync.getOwner();
0914:            }
0915:
0916:            /**
0917:             * Queries the number of read locks held for this lock. This
0918:             * method is designed for use in monitoring system state, not for
0919:             * synchronization control.
0920:             * @return the number of read locks held.
0921:             */
0922:            public int getReadLockCount() {
0923:                return sync.getReadLockCount();
0924:            }
0925:
0926:            /**
0927:             * Queries if the write lock is held by any thread. This method is
0928:             * designed for use in monitoring system state, not for
0929:             * synchronization control.
0930:             * @return <tt>true</tt> if any thread holds write lock and 
0931:             * <tt>false</tt> otherwise.
0932:             */
0933:            public boolean isWriteLocked() {
0934:                return sync.isWriteLocked();
0935:            }
0936:
0937:            /**
0938:             * Queries if the write lock is held by the current thread. 
0939:             * @return <tt>true</tt> if current thread holds this lock and 
0940:             * <tt>false</tt> otherwise.
0941:             */
0942:            public boolean isWriteLockedByCurrentThread() {
0943:                return sync.isHeldExclusively();
0944:            }
0945:
0946:            /**
0947:             * Queries the number of reentrant write holds on this lock by the
0948:             * current thread.  A writer thread has a hold on a lock for
0949:             * each lock action that is not matched by an unlock action.
0950:             *
0951:             * @return the number of holds on this lock by the current thread,
0952:             * or zero if this lock is not held by the current thread.
0953:             */
0954:            public int getWriteHoldCount() {
0955:                return sync.getWriteHoldCount();
0956:            }
0957:
0958:            /**
0959:             * Returns a collection containing threads that may be waiting to
0960:             * acquire the write lock.  Because the actual set of threads may
0961:             * change dynamically while constructing this result, the returned
0962:             * collection is only a best-effort estimate.  The elements of the
0963:             * returned collection are in no particular order.  This method is
0964:             * designed to facilitate construction of subclasses that provide
0965:             * more extensive lock monitoring facilities.
0966:             * @return the collection of threads
0967:             */
0968:            protected Collection<Thread> getQueuedWriterThreads() {
0969:                return sync.getExclusiveQueuedThreads();
0970:            }
0971:
0972:            /**
0973:             * Returns a collection containing threads that may be waiting to
0974:             * acquire the read lock.  Because the actual set of threads may
0975:             * change dynamically while constructing this result, the returned
0976:             * collection is only a best-effort estimate.  The elements of the
0977:             * returned collection are in no particular order.  This method is
0978:             * designed to facilitate construction of subclasses that provide
0979:             * more extensive lock monitoring facilities.
0980:             * @return the collection of threads
0981:             */
0982:            protected Collection<Thread> getQueuedReaderThreads() {
0983:                return sync.getSharedQueuedThreads();
0984:            }
0985:
0986:            /**
0987:             * Queries whether any threads are waiting to acquire. Note that
0988:             * because cancellations may occur at any time, a <tt>true</tt>
0989:             * return does not guarantee that any other thread will ever
0990:             * acquire.  This method is designed primarily for use in
0991:             * monitoring of the system state.
0992:             *
0993:             * @return true if there may be other threads waiting to acquire
0994:             * the lock.
0995:             */
0996:            public final boolean hasQueuedThreads() {
0997:                return sync.hasQueuedThreads();
0998:            }
0999:
1000:            /**
1001:             * Queries whether the given thread is waiting to acquire this
1002:             * lock. Note that because cancellations may occur at any time, a
1003:             * <tt>true</tt> return does not guarantee that this thread
1004:             * will ever acquire.  This method is designed primarily for use
1005:             * in monitoring of the system state.
1006:             *
1007:             * @param thread the thread
1008:             * @return true if the given thread is queued waiting for this lock.
1009:             * @throws NullPointerException if thread is null
1010:             */
1011:            public final boolean hasQueuedThread(Thread thread) {
1012:                return sync.isQueued(thread);
1013:            }
1014:
1015:            /**
1016:             * Returns an estimate of the number of threads waiting to
1017:             * acquire.  The value is only an estimate because the number of
1018:             * threads may change dynamically while this method traverses
1019:             * internal data structures.  This method is designed for use in
1020:             * monitoring of the system state, not for synchronization
1021:             * control.
1022:             * @return the estimated number of threads waiting for this lock
1023:             */
1024:            public final int getQueueLength() {
1025:                return sync.getQueueLength();
1026:            }
1027:
1028:            /**
1029:             * Returns a collection containing threads that may be waiting to
1030:             * acquire.  Because the actual set of threads may change
1031:             * dynamically while constructing this result, the returned
1032:             * collection is only a best-effort estimate.  The elements of the
1033:             * returned collection are in no particular order.  This method is
1034:             * designed to facilitate construction of subclasses that provide
1035:             * more extensive monitoring facilities.
1036:             * @return the collection of threads
1037:             */
1038:            protected Collection<Thread> getQueuedThreads() {
1039:                return sync.getQueuedThreads();
1040:            }
1041:
1042:            /**
1043:             * Queries whether any threads are waiting on the given condition
1044:             * associated with the write lock. Note that because timeouts and
1045:             * interrupts may occur at any time, a <tt>true</tt> return does
1046:             * not guarantee that a future <tt>signal</tt> will awaken any
1047:             * threads.  This method is designed primarily for use in
1048:             * monitoring of the system state.
1049:             * @param condition the condition
1050:             * @return <tt>true</tt> if there are any waiting threads.
1051:             * @throws IllegalMonitorStateException if this lock 
1052:             * is not held
1053:             * @throws IllegalArgumentException if the given condition is
1054:             * not associated with this lock
1055:             * @throws NullPointerException if condition null
1056:             */
1057:            public boolean hasWaiters(Condition condition) {
1058:                if (condition == null)
1059:                    throw new NullPointerException();
1060:                if (!(condition instanceof  AbstractQueuedSynchronizer.ConditionObject))
1061:                    throw new IllegalArgumentException("not owner");
1062:                return sync
1063:                        .hasWaiters((AbstractQueuedSynchronizer.ConditionObject) condition);
1064:            }
1065:
1066:            /**
1067:             * Returns an estimate of the number of threads waiting on the
1068:             * given condition associated with the write lock. Note that because
1069:             * timeouts and interrupts may occur at any time, the estimate
1070:             * serves only as an upper bound on the actual number of waiters.
1071:             * This method is designed for use in monitoring of the system
1072:             * state, not for synchronization control.
1073:             * @param condition the condition
1074:             * @return the estimated number of waiting threads.
1075:             * @throws IllegalMonitorStateException if this lock 
1076:             * is not held
1077:             * @throws IllegalArgumentException if the given condition is
1078:             * not associated with this lock
1079:             * @throws NullPointerException if condition null
1080:             */
1081:            public int getWaitQueueLength(Condition condition) {
1082:                if (condition == null)
1083:                    throw new NullPointerException();
1084:                if (!(condition instanceof  AbstractQueuedSynchronizer.ConditionObject))
1085:                    throw new IllegalArgumentException("not owner");
1086:                return sync
1087:                        .getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject) condition);
1088:            }
1089:
1090:            /**
1091:             * Returns a collection containing those threads that may be
1092:             * waiting on the given condition associated with the write lock.
1093:             * Because the actual set of threads may change dynamically while
1094:             * constructing this result, the returned collection is only a
1095:             * best-effort estimate. The elements of the returned collection
1096:             * are in no particular order.  This method is designed to
1097:             * facilitate construction of subclasses that provide more
1098:             * extensive condition monitoring facilities.
1099:             * @param condition the condition
1100:             * @return the collection of threads
1101:             * @throws IllegalMonitorStateException if this lock 
1102:             * is not held
1103:             * @throws IllegalArgumentException if the given condition is
1104:             * not associated with this lock
1105:             * @throws NullPointerException if condition null
1106:             */
1107:            protected Collection<Thread> getWaitingThreads(Condition condition) {
1108:                if (condition == null)
1109:                    throw new NullPointerException();
1110:                if (!(condition instanceof  AbstractQueuedSynchronizer.ConditionObject))
1111:                    throw new IllegalArgumentException("not owner");
1112:                return sync
1113:                        .getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject) condition);
1114:            }
1115:
1116:            /**
1117:             * Returns a string identifying this lock, as well as its lock state.
1118:             * The state, in brackets, includes the String &quot;Write locks =&quot;
1119:             * follwed by the number of reentrantly held write locks, and the
1120:             * String &quot;Read locks =&quot; followed by the number of held
1121:             * read locks.
1122:             * @return a string identifying this lock, as well as its lock state.
1123:             */
1124:            public String toString() {
1125:                int c = sync.getCount();
1126:                int w = exclusiveCount(c);
1127:                int r = sharedCount(c);
1128:
1129:                return super .toString() + "[Write locks = " + w
1130:                        + ", Read locks = " + r + "]";
1131:            }
1132:
1133:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.