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
23   * {@link org.apache.commons.transaction.locking.ReadWriteUpgradeLock}s on
24   * resources. <br>
25   * <br>
26   * <p>
27   * The idea (as explained by Jim LoVerde) is that only one owner can hold an
28   * upgrade lock, but while that is held, it is possible for read locks to exist
29   * and/or be obtained, and when the request is made to upgrade to a write lock
30   * by the same owner, the lock manager prevents additional read locks until the
31   * write lock can be aquired.
32   * </p>
33   * <p>
34   * In this sense the write lock becomes preferred over all other locks when it gets upgraded from
35   * a upgrate lock. Preferred means that if it has to wait and others wait as well it will be
36   * served before all other none preferred locking requests.
37   * </p>
38   * 
39   * @version $Id: ReadWriteUpgradeLockManager.java 493628 2007-01-07 01:42:48Z joerg $
40   * 
41   * @see ReadWriteUpgradeLock
42   * @since 1.1
43   */
44  public class ReadWriteUpgradeLockManager extends ReadWriteLockManager {
45  
46      /**
47       * Creates a new read/write/upgrade lock manager.
48       * 
49       * @param logger generic logger used for all kind of debug logging
50       * @param timeoutMSecs specifies the maximum time to wait for a lock in milliseconds
51       */
52      public ReadWriteUpgradeLockManager(LoggerFacade logger, long timeoutMSecs) {
53          super(ReadWriteUpgradeLock.WRITE_LOCK, logger, timeoutMSecs);
54      }
55  
56      /**
57       * Tries to acquire a reentrant upgrade lock on a resource. <br>
58       * <br>
59       * This method does not block, but immediatly returns. If a lock is not
60       * available <code>false</code> will be returned.
61       * 
62       * @param ownerId
63       *            a unique id identifying the entity that wants to acquire this
64       *            lock
65       * @param resourceId
66       *            the resource to get the lock for
67       * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
68       */
69      public boolean tryUpgradeLock(Object ownerId, Object resourceId) {
70          return tryLock(ownerId, resourceId, ReadWriteUpgradeLock.UPGRADE_LOCK, true);
71      }
72  
73      /**
74       * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
75       * <br>
76       * This method does not block, but immediatly returns. If a lock is not
77       * available <code>false</code> will be returned.
78       * 
79       * @param ownerId
80       *            a unique id identifying the entity that wants to acquire this
81       *            lock
82       * @param resourceId
83       *            the resource to get the lock for
84       * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
85       */
86      public boolean tryWriteLock(Object ownerId, Object resourceId) {
87          return tryLock(ownerId, resourceId, ReadWriteUpgradeLock.WRITE_LOCK, true);
88      }
89  
90      /**
91       * Tries to acquire a reentrant upgrade lock on a resource. <br>
92       * <br>
93       * This method blocks and waits for the lock in case it is not avaiable. If
94       * there is a timeout or a deadlock or the thread is interrupted a
95       * LockException is thrown.
96       * 
97       * @param ownerId
98       *            a unique id identifying the entity that wants to acquire this
99       *            lock
100      * @param resourceId
101      *            the resource to get the level for
102      * @throws LockException
103      *             will be thrown when the lock can not be acquired
104      */
105     public void upgradeLock(Object ownerId, Object resourceId) throws LockException {
106         super.lock(ownerId, resourceId, ReadWriteUpgradeLock.UPGRADE_LOCK, true);
107     }
108 
109     /**
110      * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
111      * <br>
112      * This method blocks and waits for the lock in case it is not avaiable. If
113      * there is a timeout or a deadlock or the thread is interrupted a
114      * LockException is thrown.
115      * 
116      * @param ownerId
117      *            a unique id identifying the entity that wants to acquire this
118      *            lock
119      * @param resourceId
120      *            the resource to get the level for
121      * @throws LockException
122      *             will be thrown when the lock can not be acquired
123      */
124     public void writeLock(Object ownerId, Object resourceId) throws LockException {
125         super.lock(ownerId, resourceId, ReadWriteUpgradeLock.WRITE_LOCK, true);
126     }
127 
128     protected GenericLock createLock(Object resourceId) {
129         synchronized (globalLocks) {
130             GenericLock lock = new ReadWriteUpgradeLock(resourceId, logger);
131             globalLocks.put(resourceId, lock);
132             return lock;
133         }
134     }
135 
136 }