001: /*
002: * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
003: * Copyright (C) 2005 - Javolution (http://javolution.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package javolution.util;
010:
011: /**
012: * <p> This class represents a reentrant lock with the same semantics as
013: * built-in Java synchronized locks: Once a thread has a lock, it can
014: * re-obtain it any number of times without blocking. </p>
015: *
016: * @author <a href="http://gee.cs.oswego.edu/dl/">Doug Lea</a>
017: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
018: * @version 1.0, October 4, 2004
019: */
020: public class ReentrantLock {
021:
022: /**
023: * Holds the owner of this lock.
024: */
025: private Thread _owner;
026:
027: /**
028: * Holds the number of time this lock has been acquired by its owner.
029: */
030: private long _count;
031:
032: /**
033: * Default constructor.
034: */
035: public ReentrantLock() {
036: }
037:
038: /**
039: * Acquires the lock.
040: */
041: public void lock() {
042: Thread caller = Thread.currentThread();
043: synchronized (this ) {
044: if (caller == _owner) {
045: _count++;
046: } else {
047: try {
048: while (_owner != null) {
049: this .wait();
050: }
051: _owner = caller;
052: _count = 1;
053: } catch (InterruptedException exception) {
054: return;
055: }
056: }
057: }
058: }
059:
060: /**
061: * Acquires the lock only if it not held by another thread.
062: *
063: * @return <code>true</code> if the lock was free and was acquired by the
064: * current thread, or the lock was already held by the current
065: * thread; <code>false</code> otherwise.
066: */
067: public boolean tryLock() {
068: synchronized (this ) {
069: if (_owner == null) {
070: lock();
071: return true;
072: } else {
073: return false;
074: }
075: }
076: }
077:
078: /**
079: * Attempts to release this lock. The lock is actually released if at
080: * least as many {@link #unlock} as {@link #lock} have been performed
081: * on this {@link ReentrantLock} by the current thread.
082: *
083: * throws IllegalMonitorStateExeception if the current thread does not hold
084: * this lock.
085: */
086: public void unlock() {
087: synchronized (this ) {
088: if (Thread.currentThread() == _owner) {
089: if (--_count == 0) {
090: _owner = null;
091: this .notify();
092: }
093: } else {
094: throw new IllegalMonitorStateException(
095: "Current thread does not hold this lock");
096: }
097: }
098: }
099:
100: /**
101: * Returns the thread owner of this {@link ReentrantLock}.
102: *
103: * @return the owner of this lock.
104: */
105: public Thread getOwner() {
106: synchronized (this) {
107: return _owner;
108: }
109: }
110: }
|