2 * Copyright 2005-2010 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.concurrency;
18 import java.util.HashSet;
21 * Read-write lock for allowing multiple concurrent readers or at most one
22 * writer. This implementation does not aim for high performance but for
23 * robustness and simplicity. Users of this class should not synchronize on
24 * objects of this class.
26 * This class was originally developed for a Java developer certification. It is
27 * deprecated now and {@link java.util.concurrent.locks.ReadWriteLock} should be
31 public class ReadWriteLock {
33 * Sets containing the references to the threads that are currently reading.
34 * This administration is useful to check that the lock has already been
35 * acquired before it is release. This check adds robustness to the
38 private HashSet<Thread> readers;
41 * The thread that has acquired the lock for writing or null if no such
42 * thread exists currently.
44 private Thread writer;
47 * Constructs read-write lock.
49 public ReadWriteLock() {
50 readers = new HashSet<Thread>();
55 * Acquires the lock for reading. This call will block until the lock can be
58 * @throws IllegalStateException
59 * Thrown if the read or write lock is already acquired.
61 public synchronized void acquireRead() {
62 if (readers.contains(Thread.currentThread())) {
63 throw new IllegalStateException(
64 "Read lock already acquired by current thread: " +
65 Thread.currentThread());
68 if (writer == Thread.currentThread()) {
69 throw new IllegalStateException(
70 "Trying to acquire the read lock while already holding a write lock: " +
71 Thread.currentThread());
74 while (writer != null) {
77 } catch (InterruptedException e) {
82 readers.add(Thread.currentThread());
86 * Releases the lock for reading. Note: This implementation assumes that the
87 * lock has already been acquired for reading previously.
89 * @throws IllegalStateException
90 * Thrown when the lock was not acquired by this thread.
92 public synchronized void releaseRead() {
93 if (!readers.remove(Thread.currentThread())) {
94 throw new IllegalStateException(
95 "Cannot release read lock because current thread has not acquired it.");
98 if (readers.size() == 0) {
104 * Acquires the lock for writing. This call will block until the lock has
107 * @throws IllegalStateException
108 * Thrown if the read or write lock is already acquired.
110 public synchronized void acquireWrite() {
111 if (writer == Thread.currentThread()) {
112 throw new IllegalStateException(
113 "Trying to acquire a write lock while already holding the write lock: " +
114 Thread.currentThread());
117 if (readers.contains(Thread.currentThread())) {
118 throw new IllegalStateException(
119 "Trying to acquire a write lock while already holding the read lock: " +
120 Thread.currentThread());
123 // wait until there are no more writers and no more
125 while ((writer != null) || (readers.size() > 0)) {
128 } catch (InterruptedException e) {
133 writer = Thread.currentThread();
135 // notification not necessary since all writers and
136 // readers are now blocked by this thread.
140 * Releases the lock for writing.
142 * @throws IllegalStateException
143 * Thrown when the lock was not acquired.
145 public synchronized void releaseWrite() {
146 if (writer != Thread.currentThread()) {
147 throw new IllegalStateException(
148 "Cannot release write lock because it was not acquired. ");