001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)ReentrantReadWriteLock.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.management.util;
030:
031: import java.util.ArrayList;
032:
033: /**
034: * This is a implementation of a tailored subset of java.util.concurrent.locks.ReentrantReadWriteLock for
035: * pre J2SE 5.0 systems. The implemented class/interfaces/methods are compatible at compile time.
036: *
037: * @author Sun Microsystems, Inc
038: */
039: public class ReentrantReadWriteLock {
040: private Object mSync;
041: private ReadLock mReadLock;
042: private WriteLock mWriteLock;
043: private ArrayList mReaders;
044: private int mReadCount;
045: private Thread mWriter;
046: private int mWriterCount;
047: private ArrayList mWaitingReaders;
048: private ArrayList mWaitingWriters;
049: private int mState;
050: static final int NONE = 0;
051: static final int READ = 1;
052: static final int WRITE = 2;
053:
054: /** Creates a new instance of RentrantReadWriteLock */
055: public ReentrantReadWriteLock() {
056: mWriteLock = new WriteLock();
057: mReadLock = new ReadLock();
058: mReaders = new ArrayList();
059: mWaitingReaders = new ArrayList();
060: mWaitingWriters = new ArrayList();
061: mWriter = null;
062: mState = NONE;
063: mWriterCount = 0;
064: mReadCount = 0;
065: mSync = this ;
066: }
067:
068: public ReadLock readLock() {
069: return (mReadLock);
070: }
071:
072: public WriteLock writeLock() {
073: return (mWriteLock);
074: }
075:
076: public boolean isWriteLockedByCurrentThread() {
077: return (mWriter == Thread.currentThread());
078: }
079:
080: synchronized int getReaders() {
081: return (mReaders.size());
082: }
083:
084: synchronized int getWaitingReaders() {
085: return (mWaitingReaders.size());
086: }
087:
088: synchronized int getWriters() {
089: return (mWriterCount);
090: }
091:
092: synchronized int getWaitingWriters() {
093: return (mWaitingWriters.size());
094: }
095:
096: synchronized int getState() {
097: return (mState);
098: }
099:
100: public interface Lock {
101: public void lock();
102:
103: public void unlock();
104: }
105:
106: public class ReadLock implements Lock {
107:
108: public boolean tryLock(long interval, TimeUnit unit)
109: throws java.lang.InterruptedException {
110: Thread t = Thread.currentThread();
111:
112: synchronized (mSync) {
113: long endTime = 0;
114:
115: while (!doLock(t)) {
116: try {
117: if (endTime == 0) {
118: endTime = System.currentTimeMillis()
119: + unit.getMilliseconds() * interval;
120: }
121:
122: mSync.wait(unit.getMilliseconds() * interval);
123: } finally {
124: mWaitingReaders.remove(t);
125: }
126: if (System.currentTimeMillis() > endTime) {
127: return (false);
128: }
129: }
130: }
131: return (true);
132: }
133:
134: public void lock() {
135: Thread t = Thread.currentThread();
136:
137: synchronized (mSync) {
138: while (!doLock(t)) {
139: try {
140: try {
141: mSync.wait();
142: } catch (java.lang.InterruptedException ie) {
143: }
144: } finally {
145: mWaitingReaders.remove(t);
146: }
147: }
148: }
149: }
150:
151: private boolean doLock(Thread t) {
152: if (mState == NONE) {
153: mReaders.add(t);
154: mState = READ;
155: mReadCount++;
156: return (true);
157: } else if (mState == READ) {
158: if (mWaitingWriters.isEmpty() || mReaders.contains(t)
159: || mReadCount < 4) {
160: mReaders.add(t);
161: return (true);
162: }
163: } else {
164: if (mWriter == t) {
165: mReaders.add(t);
166: return (true);
167: }
168: }
169: mWaitingReaders.add(t);
170: return (false);
171: }
172:
173: public void unlock() {
174: Thread t = Thread.currentThread();
175:
176: synchronized (mSync) {
177: if (mState == NONE || !mReaders.remove(t)) {
178: throw new RuntimeException("Lock not held");
179: }
180: if (mState == READ) {
181: if (mReaders.isEmpty()) {
182: mState = NONE;
183: mSync.notifyAll();
184: }
185: }
186: }
187: }
188: }
189:
190: public class WriteLock implements Lock {
191: public boolean tryLock(long interval, TimeUnit unit)
192: throws java.lang.InterruptedException {
193: Thread t = Thread.currentThread();
194:
195: synchronized (mSync) {
196: long endTime = 0;
197:
198: while (!doLock(t)) {
199: try {
200: if (endTime == 0) {
201: endTime = System.currentTimeMillis()
202: + unit.getMilliseconds() * interval;
203: }
204:
205: mSync.wait(unit.getMilliseconds() * interval);
206: } finally {
207: mWaitingWriters.remove(t);
208: }
209: if (System.currentTimeMillis() > endTime) {
210: return (false);
211: }
212: }
213: }
214: return (true);
215: }
216:
217: public void lock() {
218: Thread t = Thread.currentThread();
219:
220: synchronized (mSync) {
221: while (!doLock(t)) {
222: try {
223: try {
224: mSync.wait();
225: } catch (java.lang.InterruptedException iE) {
226: }
227: } finally {
228: mWaitingWriters.remove(t);
229: }
230: }
231: }
232: }
233:
234: private boolean doLock(Thread t) {
235: if (mState == NONE) {
236: mWriter = t;
237: mWriterCount++;
238: mState = WRITE;
239: mReadCount = 0;
240: return (true);
241: } else {
242: if (mState == WRITE && mWriter == t) {
243: mWriterCount++;
244: return (true);
245: }
246: mWaitingWriters.add(t);
247: }
248: return (false);
249: }
250:
251: public void unlock() {
252: Thread t = Thread.currentThread();
253: boolean wakeReaders = false;
254:
255: synchronized (mSync) {
256: if (mState == WRITE && mWriter == t) {
257: if (--mWriterCount > 0) {
258: return;
259: }
260: mWriter = null;
261: if (mReaders.contains(t)) {
262: mState = READ;
263: } else {
264: mState = NONE;
265: }
266: mSync.notifyAll();
267: } else {
268: throw new RuntimeException("Lock not held");
269: }
270: }
271: }
272: }
273:
274: }
|