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, LoggerFacade logger, long timeoutMSecs)
040 throws IllegalArgumentException {
041 super(maxLockLevel, logger, timeoutMSecs);
042 }
043
044 /**
045 * Tries to acquire a shared, reentrant read lock on a resource. <br>
046 * <br>
047 * This method does not block, but immediatly returns. If a lock is not
048 * available <code>false</code> will be returned.
049 *
050 * @param ownerId
051 * a unique id identifying the entity that wants to acquire this
052 * lock
053 * @param resourceId
054 * the resource to get the lock for
055 * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
056 */
057 public boolean tryReadLock(Object ownerId, Object resourceId) {
058 return tryLock(ownerId, resourceId, ReadWriteLock.READ_LOCK, true);
059 }
060
061 /**
062 * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
063 * <br>
064 * This method does not block, but immediatly returns. If a lock is not
065 * available <code>false</code> will be returned.
066 *
067 * @param ownerId
068 * a unique id identifying the entity that wants to acquire this
069 * lock
070 * @param resourceId
071 * the resource to get the lock for
072 * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
073 */
074 public boolean tryWriteLock(Object ownerId, Object resourceId) {
075 return tryLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK, true);
076 }
077
078 /**
079 * Determines if a shared, reentrant read lock on a resource
080 * <em>could</em> be acquired without actually acquiring it. <br>
081 * <br>
082 * This method does not block, but immediatly returns. If a lock is not
083 * available <code>false</code> will be returned.
084 *
085 * @param ownerId
086 * a unique id identifying the entity that wants to acquire this
087 * lock
088 * @param resourceId
089 * the resource to get the lock for
090 * @return <code>true</code> if the lock could be acquired, <code>false</code> otherwise
091 */
092 public boolean checkReadLock(Object ownerId, Object resourceId) {
093 return checkLock(ownerId, resourceId, ReadWriteLock.READ_LOCK, true);
094 }
095
096 /**
097 * Determines if an exclusive, reentrant write lock on a resource
098 * is held by an owner. <br>
099 *
100 * @param ownerId
101 * a unique id identifying the entity that wants to check this
102 * lock
103 * @param resourceId
104 * the resource to get the lock for
105 * @return <code>true</code> if the lock is held by the owner, <code>false</code> otherwise
106 */
107 public boolean hasWriteLock(Object ownerId, Object resourceId) {
108 return hasLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK);
109 }
110
111 /**
112 * Determines if a shared, reentrant read lock on a resource
113 * is held by an owner. <br>
114 *
115 * @param ownerId
116 * a unique id identifying the entity that wants to check this
117 * lock
118 * @param resourceId
119 * the resource to get the lock for
120 * @return <code>true</code> if the lock is held by the owner, <code>false</code> otherwise
121 */
122 public boolean hasReadLock(Object ownerId, Object resourceId) {
123 return hasLock(ownerId, resourceId, ReadWriteLock.READ_LOCK);
124 }
125
126 /**
127 * Determines if an exclusive, reentrant write lock on a resource
128 * <em>could</em> be acquired without actually acquiring it. <br>
129 * <br>
130 * This method does not block, but immediatly returns. If a lock is not
131 * available <code>false</code> will be returned.
132 *
133 * @param ownerId
134 * a unique id identifying the entity that wants to acquire this
135 * lock
136 * @param resourceId
137 * the resource to get the lock for
138 * @return <code>true</code> if the lock could be acquired, <code>false</code> otherwise
139 */
140 public boolean checkWriteLock(Object ownerId, Object resourceId) {
141 return checkLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK, true);
142 }
143
144 /**
145 * Tries to acquire a shared, reentrant read lock on a resource. <br>
146 * <br>
147 * This method blocks and waits for the lock in case it is not avaiable. If
148 * there is a timeout or a deadlock or the thread is interrupted a
149 * LockException is thrown.
150 *
151 * @param ownerId
152 * a unique id identifying the entity that wants to acquire this
153 * lock
154 * @param resourceId
155 * the resource to get the lock for
156 * @throws LockException
157 * will be thrown when the lock can not be acquired
158 */
159 public void readLock(Object ownerId, Object resourceId) throws LockException {
160 lock(ownerId, resourceId, ReadWriteLock.READ_LOCK, GenericLock.COMPATIBILITY_REENTRANT,
161 false, globalTimeoutMSecs);
162 }
163
164 /**
165 * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
166 * <br>
167 * This method blocks and waits for the lock in case it is not avaiable. If
168 * there is a timeout or a deadlock or the thread is interrupted a
169 * LockException is thrown.
170 *
171 * @param ownerId
172 * a unique id identifying the entity that wants to acquire this
173 * lock
174 * @param resourceId
175 * the resource to get the lock for
176 * @throws LockException
177 * will be thrown when the lock can not be acquired
178 */
179 public void writeLock(Object ownerId, Object resourceId) throws LockException {
180 lock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK, GenericLock.COMPATIBILITY_REENTRANT,
181 true, globalTimeoutMSecs);
182 }
183
184 protected GenericLock createLock(Object resourceId) {
185 synchronized (globalLocks) {
186 GenericLock lock = new ReadWriteLock(resourceId, logger);
187 globalLocks.put(resourceId, lock);
188 return lock;
189 }
190 }
191
192 }