KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > transaction > locking > ReadWriteUpgradeLock


1 /*
2  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//transaction/src/java/org/apache/commons/transaction/locking/ReadWriteUpgradeLock.java,v 1.3 2005/01/09 15:12:11 ozeigermann Exp $
3 <<<<<<< .mine
4  * $Revision: 1.3 $
5  * $Date: 2005-02-26 14:16:14 +0100 (Sa, 26 Feb 2005) $
6 =======
7  * $Revision$
8  * $Date: 2005-02-26 14:16:14 +0100 (Sa, 26 Feb 2005) $
9 >>>>>>> .r168169
10  *
11  * ====================================================================
12  *
13  * Copyright 2004 The Apache Software Foundation
14  *
15  * Licensed under the Apache License, Version 2.0 (the "License");
16  * you may not use this file except in compliance with the License.
17  * You may obtain a copy of the License at
18  *
19  * http://www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing, software
22  * distributed under the License is distributed on an "AS IS" BASIS,
23  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24  * See the License for the specific language governing permissions and
25  * limitations under the License.
26  *
27  */

28
29 package org.apache.commons.transaction.locking;
30
31 import org.apache.commons.transaction.util.LoggerFacade;
32
33 /**
34  * Convenience implementation of a read/write lock with an option for upgrade
35  * based on {@link ReadWriteUpgradeLockLock}.<br>
36  * <br>
37  * Reads are shared which means there can be any number of concurrent read
38  * accesses allowed by this lock. Writes are exclusive. This means when there is
39  * a write access no other access neither read nor write are allowed by this
40  * lock. <br>
41  * <br>
42  * <p>
43  * The idea (as explained by Jim LoVerde) on an upgrade lock is that only one owner can hold an
44  * upgrade lock, but while that is held, it is possible for read locks to exist
45  * and/or be obtained, and when the request is made to upgrade to a write lock
46  * by the same owner, the lock manager prevents additional read locks until the
47  * write lock can be aquired.
48  * </p>
49  * <p>
50  * In this sense the write lock becomes preferred over all other locks when it gets upgraded from
51  * a upgrate lock. Preferred means that if it has to wait and others wait as well it will be
52  * served before all other none preferred locking requests.
53  * </p>
54  *
55  * Calls to {@link #acquireRead(Object, long)}, {@link #acquireUpgrade(Object, long)} and
56  * {@link #acquireWrite(Object, long)} are blocking and reentrant. Blocking
57  * means they will wait if they can not acquire the descired access, reentrant
58  * means that a lock request by a specific owner will always be compatible with
59  * other accesses on this lock by the same owner. E.g. if you already have a
60  * lock for writing and you try to acquire write access again you will not be
61  * blocked by this first lock, while others of course will be. This is the
62  * natural way you already know from Java monitors and synchronized blocks.
63  *
64  * @version $Revision$
65  *
66  * @see GenericLock
67  * @see org.apache.commons.transaction.locking.ReadWriteLock
68  * @see ReadWriteUpgradeLockManager
69  * @since 1.1
70  */

71 public class ReadWriteUpgradeLock extends GenericLock {
72
73     public static final int NO_LOCK = 0;
74
75     public static final int READ_LOCK = 1;
76
77     public static final int UPGRADE_LOCK = 2;
78
79     public static final int WRITE_LOCK = 3;
80
81     /**
82      * Creates a new read/write/upgrade lock.
83      *
84      * @param resourceId
85      * identifier for the resource associated to this lock
86      * @param logger
87      * generic logger used for all kind of debug logging
88      */

89     public ReadWriteUpgradeLock(Object JavaDoc resourceId, LoggerFacade logger) {
90         super(resourceId, WRITE_LOCK, logger);
91     }
92
93     /**
94      * Tries to acquire a blocking, reentrant read lock. A read lock is
95      * compatible with other read locks, but not with a write lock.
96      *
97      * @param ownerId
98      * a unique id identifying the entity that wants to acquire a
99      * certain lock level on this lock
100      * @param timeoutMSecs
101      * if blocking is enabled by the <code>wait</code> parameter
102      * this specifies the maximum wait time in milliseconds
103      * @return <code>true</code> if the lock actually was acquired
104      * @throws InterruptedException
105      * when the thread waiting on this method is interrupted
106      */

107     public boolean acquireRead(Object JavaDoc ownerId, long timeoutMSecs) throws InterruptedException JavaDoc {
108         return acquire(ownerId, READ_LOCK, true, true, timeoutMSecs);
109     }
110
111     /**
112      * Tries to acquire a reentrant upgrade lock on a resource. <br>
113      *
114      * @param ownerId
115      * a unique id identifying the entity that wants to acquire a
116      * certain lock level on this lock
117      * @param timeoutMSecs
118      * if blocking is enabled by the <code>wait</code> parameter
119      * this specifies the maximum wait time in milliseconds
120      * @return <code>true</code> if the lock actually was acquired
121      * @throws InterruptedException
122      * when the thread waiting on this method is interrupted
123      */

124     public boolean acquireUpgrade(Object JavaDoc ownerId, long timeoutMSecs) throws InterruptedException JavaDoc {
125         return acquire(ownerId, UPGRADE_LOCK, true, true, timeoutMSecs);
126     }
127
128     /**
129      * Tries to acquire a blocking, reentrant write lock. A write lock is
130      * incompatible with any another read or write lock and is thus exclusive.
131      *
132      * @param ownerId
133      * a unique id identifying the entity that wants to acquire a
134      * certain lock level on this lock
135      * @param timeoutMSecs
136      * if blocking is enabled by the <code>wait</code> parameter
137      * this specifies the maximum wait time in milliseconds
138      * @return <code>true</code> if the lock actually was acquired
139      * @throws InterruptedException
140      * when the thread waiting on this method is interrupted
141      */

142     public boolean acquireWrite(Object JavaDoc ownerId, long timeoutMSecs) throws InterruptedException JavaDoc {
143         // in case we already had an upgrade lock, this wait lock will become preferred
144
boolean preferred = getLockLevel(ownerId) == UPGRADE_LOCK;
145         return acquire(ownerId, WRITE_LOCK, true, COMPATIBILITY_REENTRANT, preferred, timeoutMSecs);
146     }
147
148     /**
149      * @see GenericLock#acquire(Object, int, boolean, int, boolean, long)
150      */

151     public synchronized boolean acquire(Object JavaDoc ownerId, int targetLockLevel, boolean wait,
152             int compatibility, boolean preferred, long timeoutMSecs) throws InterruptedException JavaDoc {
153         if (targetLockLevel == WRITE_LOCK && getLockLevel(ownerId) == UPGRADE_LOCK) {
154             preferred = true;
155         }
156         return super.acquire(ownerId, targetLockLevel, wait, compatibility, preferred, timeoutMSecs);
157     }
158
159 }
Popular Tags