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 */ 017package org.apache.commons.transaction.locking; 018 019import 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 */ 027public 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}