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 }