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 }