123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /* ========================================================================
- * JCommon : a free general purpose class library for the Java(tm) platform
- * ========================================================================
- *
- * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
- *
- * Project Info: http://www.jfree.org/jcommon/index.html
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
- * in the United States and other countries.]
- *
- * ---------------------
- * ReaderWriterLock.java
- * ---------------------
- *
- * $Id: ReaderWriterLock.java,v 1.3 2005/10/18 13:18:34 mungady Exp $
- *
- * Changes
- * -------
- * 29-Jan-2003 : Added standard header (DG);
- *
- */
- package org.jfree.threads;
- import java.util.ArrayList;
- import java.util.Iterator;
- /**
- * A reader-writer lock from "Java Threads" by Scott Oak and Henry Wong.
- *
- * @author Scott Oak and Henry Wong
- */
- public class ReaderWriterLock {
- /**
- * A node for the waiting list.
- *
- * @author Scott Oak and Henry Wong
- */
- private static class ReaderWriterNode {
- /** A reader. */
- protected static final int READER = 0;
- /** A writer. */
- protected static final int WRITER = 1;
- /** The thread. */
- protected Thread t;
- /** The state. */
- protected int state;
- /** The number of acquires.*/
- protected int nAcquires;
- /**
- * Creates a new node.
- *
- * @param t the thread.
- * @param state the state.
- */
- private ReaderWriterNode(final Thread t, final int state) {
- this.t = t;
- this.state = state;
- this.nAcquires = 0;
- }
- }
- /** The waiting threads. */
- private ArrayList waiters;
- /**
- * Default constructor.
- */
- public ReaderWriterLock() {
- this.waiters = new ArrayList();
- }
- /**
- * Grab the read lock.
- */
- public synchronized void lockRead() {
- final ReaderWriterNode node;
- final Thread me = Thread.currentThread();
- final int index = getIndex(me);
- if (index == -1) {
- node = new ReaderWriterNode(me, ReaderWriterNode.READER);
- this.waiters.add(node);
- }
- else {
- node = (ReaderWriterNode) this.waiters.get(index);
- }
- while (getIndex(me) > firstWriter()) {
- try {
- wait();
- }
- catch (Exception e) {
- System.err.println("ReaderWriterLock.lockRead(): exception.");
- System.err.print(e.getMessage());
- }
- }
- node.nAcquires++;
- }
- /**
- * Grab the write lock.
- */
- public synchronized void lockWrite() {
- final ReaderWriterNode node;
- final Thread me = Thread.currentThread();
- final int index = getIndex(me);
- if (index == -1) {
- node = new ReaderWriterNode(me, ReaderWriterNode.WRITER);
- this.waiters.add(node);
- }
- else {
- node = (ReaderWriterNode) this.waiters.get(index);
- if (node.state == ReaderWriterNode.READER) {
- throw new IllegalArgumentException("Upgrade lock");
- }
- node.state = ReaderWriterNode.WRITER;
- }
- while (getIndex(me) != 0) {
- try {
- wait();
- }
- catch (Exception e) {
- System.err.println("ReaderWriterLock.lockWrite(): exception.");
- System.err.print(e.getMessage());
- }
- }
- node.nAcquires++;
- }
- /**
- * Unlock.
- */
- public synchronized void unlock() {
- final ReaderWriterNode node;
- final Thread me = Thread.currentThread();
- final int index = getIndex(me);
- if (index > firstWriter()) {
- throw new IllegalArgumentException("Lock not held");
- }
- node = (ReaderWriterNode) this.waiters.get(index);
- node.nAcquires--;
- if (node.nAcquires == 0) {
- this.waiters.remove(index);
- }
- notifyAll();
- }
- /**
- * Returns the index of the first waiting writer.
- *
- * @return The index.
- */
- private int firstWriter() {
- final Iterator e = this.waiters.iterator();
- int index = 0;
- while (e.hasNext()) {
- final ReaderWriterNode node = (ReaderWriterNode) e.next();
- if (node.state == ReaderWriterNode.WRITER) {
- return index;
- }
- index += 1;
- }
- return Integer.MAX_VALUE;
- }
- /**
- * Returns the index of a thread.
- *
- * @param t the thread.
- *
- * @return The index.
- */
- private int getIndex(final Thread t) {
- final Iterator e = this.waiters.iterator();
- int index = 0;
- while (e.hasNext()) {
- final ReaderWriterNode node = (ReaderWriterNode) e.next();
- if (node.t == t) {
- return index;
- }
- index += 1;
- }
- return -1;
- }
- }
|