Source Code Cross Referenced for ICURWLock.java in  » Internationalization-Localization » icu4j » com » ibm » icu » impl » 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 » Internationalization Localization » icu4j » com.ibm.icu.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         *******************************************************************************
003:         * Copyright (C) 2001-2006, International Business Machines Corporation and    *
004:         * others. All Rights Reserved.                                                *
005:         *******************************************************************************
006:         */package com.ibm.icu.impl;
007:
008:        // See Allan Holub's 1999 column in JavaWorld, and Doug Lea's code for RWLocks with writer preference.
009:
010:        /**
011:         * <p>A simple Reader/Writer lock.  This assumes that there will
012:         * be little writing contention.  It also doesn't allow 
013:         * active readers to acquire and release a write lock, or
014:         * deal with priority inversion issues.</p>
015:         *
016:         * <p>Access to the lock should be enclosed in a try/finally block
017:         * in order to ensure that the lock is always released in case of
018:         * exceptions:<br><pre>
019:         * try {
020:         *     lock.acquireRead();
021:         *     // use service protected by the lock
022:         * }
023:         * finally {
024:         *     lock.releaseRead();
025:         * }
026:         * </pre></p>
027:         *
028:         * <p>The lock provides utility methods getStats and clearStats
029:         * to return statistics on the use of the lock.</p>
030:         */
031:        public class ICURWLock {
032:            private Object writeLock = new Object();
033:            private Object readLock = new Object();
034:            private int wwc; // waiting writers
035:            private int rc; // active readers, -1 if there's an active writer
036:            private int wrc; // waiting readers
037:
038:            private Stats stats = new Stats(); // maybe don't init to start...
039:
040:            /**
041:             * Internal class used to gather statistics on the RWLock.
042:             */
043:            public final static class Stats {
044:                /**
045:                 * Number of times read access granted (read count).
046:                 */
047:                public int _rc;
048:
049:                /**
050:                 * Number of times concurrent read access granted (multiple read count).
051:                 */
052:                public int _mrc;
053:
054:                /**
055:                 * Number of times blocked for read (waiting reader count).
056:                 */
057:                public int _wrc; // wait for read
058:
059:                /**
060:                 * Number of times write access granted (writer count).
061:                 */
062:                public int _wc;
063:
064:                /**
065:                 * Number of times blocked for write (waiting writer count).
066:                 */
067:                public int _wwc;
068:
069:                private Stats() {
070:                }
071:
072:                private Stats(int rc, int mrc, int wrc, int wc, int wwc) {
073:                    this ._rc = rc;
074:                    this ._mrc = mrc;
075:                    this ._wrc = wrc;
076:                    this ._wc = wc;
077:                    this ._wwc = wwc;
078:                }
079:
080:                private Stats(Stats rhs) {
081:                    this (rhs._rc, rhs._mrc, rhs._wrc, rhs._wc, rhs._wwc);
082:                }
083:
084:                /**
085:                 * Return a string listing all the stats.
086:                 */
087:                public String toString() {
088:                    return " rc: " + _rc + " mrc: " + _mrc + " wrc: " + _wrc
089:                            + " wc: " + _wc + " wwc: " + _wwc;
090:                }
091:            }
092:
093:            /**
094:             * Reset the stats.  Returns existing stats, if any.
095:             */
096:            public synchronized Stats resetStats() {
097:                Stats result = stats;
098:                stats = new Stats();
099:                return result;
100:            }
101:
102:            /**
103:             * Clear the stats (stop collecting stats).  Returns existing stats, if any.
104:             */
105:            public synchronized Stats clearStats() {
106:                Stats result = stats;
107:                stats = null;
108:                return result;
109:            }
110:
111:            /**
112:             * Return a snapshot of the current stats.  This does not reset the stats.
113:             */
114:            public synchronized Stats getStats() {
115:                return stats == null ? null : new Stats(stats);
116:            }
117:
118:            // utilities
119:
120:            private synchronized boolean gotRead() {
121:                ++rc;
122:                if (stats != null) {
123:                    ++stats._rc;
124:                    if (rc > 1)
125:                        ++stats._mrc;
126:                }
127:                return true;
128:            }
129:
130:            private synchronized boolean getRead() {
131:                if (rc >= 0 && wwc == 0) {
132:                    return gotRead();
133:                }
134:                ++wrc;
135:                return false;
136:            }
137:
138:            private synchronized boolean retryRead() {
139:                if (stats != null)
140:                    ++stats._wrc;
141:                if (rc >= 0 && wwc == 0) {
142:                    --wrc;
143:                    return gotRead();
144:                }
145:                return false;
146:            }
147:
148:            private synchronized boolean finishRead() {
149:                if (rc > 0) {
150:                    return (0 == --rc && wwc > 0);
151:                }
152:                throw new IllegalStateException("no current reader to release");
153:            }
154:
155:            private synchronized boolean gotWrite() {
156:                rc = -1;
157:                if (stats != null) {
158:                    ++stats._wc;
159:                }
160:                return true;
161:            }
162:
163:            private synchronized boolean getWrite() {
164:                if (rc == 0) {
165:                    return gotWrite();
166:                }
167:                ++wwc;
168:                return false;
169:            }
170:
171:            private synchronized boolean retryWrite() {
172:                if (stats != null)
173:                    ++stats._wwc;
174:                if (rc == 0) {
175:                    --wwc;
176:                    return gotWrite();
177:                }
178:                return false;
179:            }
180:
181:            private static final int NOTIFY_NONE = 0;
182:            private static final int NOTIFY_WRITERS = 1;
183:            private static final int NOTIFY_READERS = 2;
184:
185:            private synchronized int finishWrite() {
186:                if (rc < 0) {
187:                    rc = 0;
188:                    if (wwc > 0) {
189:                        return NOTIFY_WRITERS;
190:                    } else if (wrc > 0) {
191:                        return NOTIFY_READERS;
192:                    } else {
193:                        return NOTIFY_NONE;
194:                    }
195:                }
196:                throw new IllegalStateException("no current writer to release");
197:            }
198:
199:            /**
200:             * <p>Acquire a read lock, blocking until a read lock is
201:             * available.  Multiple readers can concurrently hold the read
202:             * lock.</p>
203:             *
204:             * <p>If there's a writer, or a waiting writer, increment the
205:             * waiting reader count and block on this.  Otherwise
206:             * increment the active reader count and return.  Caller must call
207:             * releaseRead when done (for example, in a finally block).</p> 
208:             */
209:            public void acquireRead() {
210:                if (!getRead()) {
211:                    for (;;) {
212:                        try {
213:                            synchronized (readLock) {
214:                                readLock.wait();
215:                            }
216:                            if (retryRead()) {
217:                                return;
218:                            }
219:                        } catch (InterruptedException e) {
220:                        }
221:                    }
222:                }
223:            }
224:
225:            /**
226:             * <p>Release a read lock and return.  An error will be thrown
227:             * if a read lock is not currently held.</p>
228:             *
229:             * <p>If this is the last active reader, notify the oldest
230:             * waiting writer.  Call when finished with work
231:             * controlled by acquireRead.</p>
232:             */
233:            public void releaseRead() {
234:                if (finishRead()) {
235:                    synchronized (writeLock) {
236:                        writeLock.notify();
237:                    }
238:                }
239:            }
240:
241:            /**
242:             * <p>Acquire the write lock, blocking until the write lock is
243:             * available.  Only one writer can acquire the write lock, and
244:             * when held, no readers can acquire the read lock.</p>
245:             *
246:             * <p>If there are no readers and no waiting writers, mark as
247:             * having an active writer and return.  Otherwise, add a lock to the
248:             * end of the waiting writer list, and block on it.  Caller
249:             * must call releaseWrite when done (for example, in a finally
250:             * block).<p> 
251:             */
252:            public void acquireWrite() {
253:                if (!getWrite()) {
254:                    for (;;) {
255:                        try {
256:                            synchronized (writeLock) {
257:                                writeLock.wait();
258:                            }
259:                            if (retryWrite()) {
260:                                return;
261:                            }
262:                        } catch (InterruptedException e) {
263:                        }
264:                    }
265:                }
266:            }
267:
268:            /**
269:             * <p>Release the write lock and return.  An error will be thrown
270:             * if the write lock is not currently held.</p>
271:             *
272:             * <p>If there are waiting readers, make them all active and
273:             * notify all of them.  Otherwise, notify the oldest waiting
274:             * writer, if any.  Call when finished with work controlled by
275:             * acquireWrite.</p> 
276:             */
277:            public void releaseWrite() {
278:                switch (finishWrite()) {
279:                case NOTIFY_WRITERS:
280:                    synchronized (writeLock) {
281:                        writeLock.notify();
282:                    }
283:                    break;
284:                case NOTIFY_READERS:
285:                    synchronized (readLock) {
286:                        readLock.notifyAll();
287:                    }
288:                    break;
289:                case NOTIFY_NONE:
290:                    break;
291:                }
292:            }
293:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.