View Javadoc

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 }