1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.transaction.locking; 18 19 import org.apache.commons.transaction.util.LoggerFacade; 20 21 /** 22 * Manager for {@link org.apache.commons.transaction.locking.ReadWriteLock}s on resources. 23 * 24 * @version $Id: ReadWriteLockManager.java 493628 2007-01-07 01:42:48Z joerg $ 25 * @since 1.1 26 */ 27 public class ReadWriteLockManager extends GenericLockManager { 28 29 /** 30 * Creates a new read/write lock manager. 31 * 32 * @param logger generic logger used for all kind of debug logging 33 * @param timeoutMSecs specifies the maximum time to wait for a lock in milliseconds 34 */ 35 public ReadWriteLockManager(LoggerFacade logger, long timeoutMSecs) { 36 super(ReadWriteLock.WRITE_LOCK, logger, timeoutMSecs); 37 } 38 39 protected ReadWriteLockManager(int maxLockLevel, LoggerFacade logger, long timeoutMSecs) 40 throws IllegalArgumentException { 41 super(maxLockLevel, logger, timeoutMSecs); 42 } 43 44 /** 45 * Tries to acquire a shared, reentrant read lock on a resource. <br> 46 * <br> 47 * This method does not block, but immediatly returns. If a lock is not 48 * available <code>false</code> will be returned. 49 * 50 * @param ownerId 51 * a unique id identifying the entity that wants to acquire this 52 * lock 53 * @param resourceId 54 * the resource to get the lock for 55 * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise 56 */ 57 public boolean tryReadLock(Object ownerId, Object resourceId) { 58 return tryLock(ownerId, resourceId, ReadWriteLock.READ_LOCK, true); 59 } 60 61 /** 62 * Tries to acquire an exclusive, reentrant write lock on a resource. <br> 63 * <br> 64 * This method does not block, but immediatly returns. If a lock is not 65 * available <code>false</code> will be returned. 66 * 67 * @param ownerId 68 * a unique id identifying the entity that wants to acquire this 69 * lock 70 * @param resourceId 71 * the resource to get the lock for 72 * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise 73 */ 74 public boolean tryWriteLock(Object ownerId, Object resourceId) { 75 return tryLock(ownerId, resourceId, ReadWriteLock.WRITE_LOCK, true); 76 } 77 78 /** 79 * Determines if a shared, reentrant read lock on a resource 80 * <em>could</em> be acquired without actually acquiring it. <br> 81 * <br> 82 * This method does not block, but immediatly returns. If a lock is not 83 * available <code>false</code> will be returned. 84 * 85 * @param ownerId 86 * a unique id identifying the entity that wants to acquire this 87 * lock 88 * @param resourceId 89 * the resource to get the lock for 90 * @return <code>true</code> if the lock could be acquired, <code>false</code> otherwise 91 */ 92 public boolean checkReadLock(Object ownerId, Object resourceId) { 93 return checkLock(ownerId, resourceId, ReadWriteLock.READ_LOCK, true); 94 } 95 96 /** 97 * Determines if an exclusive, reentrant write lock on a resource 98 * is held by an owner. <br> 99 * 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 }