001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.transaction.locking;
018:
019: import org.apache.commons.transaction.util.LoggerFacade;
020:
021: /**
022: * Manager for {@link org.apache.commons.transaction.locking.ReadWriteLock}s on resources.
023: *
024: * @version $Id: ReadWriteLockManager.java 493628 2007-01-07 01:42:48Z joerg $
025: * @since 1.1
026: */
027: public class ReadWriteLockManager extends GenericLockManager {
028:
029: /**
030: * Creates a new read/write lock manager.
031: *
032: * @param logger generic logger used for all kind of debug logging
033: * @param timeoutMSecs specifies the maximum time to wait for a lock in milliseconds
034: */
035: public ReadWriteLockManager(LoggerFacade logger, long timeoutMSecs) {
036: super (ReadWriteLock.WRITE_LOCK, logger, timeoutMSecs);
037: }
038:
039: protected ReadWriteLockManager(int maxLockLevel,
040: LoggerFacade logger, long timeoutMSecs)
041: throws IllegalArgumentException {
042: super (maxLockLevel, logger, timeoutMSecs);
043: }
044:
045: /**
046: * Tries to acquire a shared, reentrant read lock on a resource. <br>
047: * <br>
048: * This method does not block, but immediatly returns. If a lock is not
049: * available <code>false</code> will be returned.
050: *
051: * @param ownerId
052: * a unique id identifying the entity that wants to acquire this
053: * lock
054: * @param resourceId
055: * the resource to get the lock for
056: * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
057: */
058: public boolean tryReadLock(Object ownerId, Object resourceId) {
059: return tryLock(ownerId, resourceId, ReadWriteLock.READ_LOCK,
060: true);
061: }
062:
063: /**
064: * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
065: * <br>
066: * This method does not block, but immediatly returns. If a lock is not
067: * available <code>false</code> will be returned.
068: *
069: * @param ownerId
070: * a unique id identifying the entity that wants to acquire this
071: * lock
072: * @param resourceId
073: * the resource to get the lock for
074: * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
075: */
076: public boolean tryWriteLock(Object ownerId, Object resourceId) {
077: return tryLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK,
078: true);
079: }
080:
081: /**
082: * Determines if a shared, reentrant read lock on a resource
083: * <em>could</em> be acquired without actually acquiring it. <br>
084: * <br>
085: * This method does not block, but immediatly returns. If a lock is not
086: * available <code>false</code> will be returned.
087: *
088: * @param ownerId
089: * a unique id identifying the entity that wants to acquire this
090: * lock
091: * @param resourceId
092: * the resource to get the lock for
093: * @return <code>true</code> if the lock could be acquired, <code>false</code> otherwise
094: */
095: public boolean checkReadLock(Object ownerId, Object resourceId) {
096: return checkLock(ownerId, resourceId, ReadWriteLock.READ_LOCK,
097: true);
098: }
099:
100: /**
101: * Determines if an exclusive, reentrant write lock on a resource
102: * is held by an owner. <br>
103: *
104: * @param ownerId
105: * a unique id identifying the entity that wants to check this
106: * lock
107: * @param resourceId
108: * the resource to get the lock for
109: * @return <code>true</code> if the lock is held by the owner, <code>false</code> otherwise
110: */
111: public boolean hasWriteLock(Object ownerId, Object resourceId) {
112: return hasLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK);
113: }
114:
115: /**
116: * Determines if a shared, reentrant read lock on a resource
117: * is held by an owner. <br>
118: *
119: * @param ownerId
120: * a unique id identifying the entity that wants to check this
121: * lock
122: * @param resourceId
123: * the resource to get the lock for
124: * @return <code>true</code> if the lock is held by the owner, <code>false</code> otherwise
125: */
126: public boolean hasReadLock(Object ownerId, Object resourceId) {
127: return hasLock(ownerId, resourceId, ReadWriteLock.READ_LOCK);
128: }
129:
130: /**
131: * Determines if an exclusive, reentrant write lock on a resource
132: * <em>could</em> be acquired without actually acquiring it. <br>
133: * <br>
134: * This method does not block, but immediatly returns. If a lock is not
135: * available <code>false</code> will be returned.
136: *
137: * @param ownerId
138: * a unique id identifying the entity that wants to acquire this
139: * lock
140: * @param resourceId
141: * the resource to get the lock for
142: * @return <code>true</code> if the lock could be acquired, <code>false</code> otherwise
143: */
144: public boolean checkWriteLock(Object ownerId, Object resourceId) {
145: return checkLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK,
146: true);
147: }
148:
149: /**
150: * Tries to acquire a shared, reentrant read lock on a resource. <br>
151: * <br>
152: * This method blocks and waits for the lock in case it is not avaiable. If
153: * there is a timeout or a deadlock or the thread is interrupted a
154: * LockException is thrown.
155: *
156: * @param ownerId
157: * a unique id identifying the entity that wants to acquire this
158: * lock
159: * @param resourceId
160: * the resource to get the lock for
161: * @throws LockException
162: * will be thrown when the lock can not be acquired
163: */
164: public void readLock(Object ownerId, Object resourceId)
165: throws LockException {
166: lock(ownerId, resourceId, ReadWriteLock.READ_LOCK,
167: GenericLock.COMPATIBILITY_REENTRANT, false,
168: globalTimeoutMSecs);
169: }
170:
171: /**
172: * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
173: * <br>
174: * This method blocks and waits for the lock in case it is not avaiable. If
175: * there is a timeout or a deadlock or the thread is interrupted a
176: * LockException is thrown.
177: *
178: * @param ownerId
179: * a unique id identifying the entity that wants to acquire this
180: * lock
181: * @param resourceId
182: * the resource to get the lock for
183: * @throws LockException
184: * will be thrown when the lock can not be acquired
185: */
186: public void writeLock(Object ownerId, Object resourceId)
187: throws LockException {
188: lock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK,
189: GenericLock.COMPATIBILITY_REENTRANT, true,
190: globalTimeoutMSecs);
191: }
192:
193: protected GenericLock createLock(Object resourceId) {
194: synchronized (globalLocks) {
195: GenericLock lock = new ReadWriteLock(resourceId, logger);
196: globalLocks.put(resourceId, lock);
197: return lock;
198: }
199: }
200:
201: }
|