?? lockmanager.java
字號:
package lockmgr;import java.util.BitSet;import java.util.Vector;/** * Implements a Lock Manager. Each Resource Manager creates one * instance of this class, to which all lock requests are directed. */public class LockManager{ /* Lock request type. */ public static final int READ = 0; public static final int WRITE = 1; /* A lock request is considered deadlocked after 10 sec. */ private static int DEADLOCK_TIMEOUT = 10000; private static int TABLE_SIZE = 2039; private static TPHashTable lockTable = new TPHashTable(TABLE_SIZE); private static TPHashTable stampTable = new TPHashTable(TABLE_SIZE); private static TPHashTable waitTable = new TPHashTable(TABLE_SIZE); /** * Each Resource Manager needs to construct one instance of the * LockManager. */ public LockManager() { super(); } /** * Locks the data item identified by <tt>strData</tt> in mode * <tt>lockType</tt> on behalf of the transaction with id * <tt>xid</tt>. This is a blocking call; if the item is currently * locked in a conflicting lock mode, the requesting thread will * sleep until the lock becomes available or a deadlock is * detected. * * @param xid Transaction Identifier, should be non-negative. * @param strData identifies the data element to be locked; should be non-null. * @param lockType one of LockManager.READ or LockManager.WRITE * @return true if operation succeeded; false if not (due to invalid parameters). * * @throws DeadlockException if deadlock is detected (using a timeout) */ public boolean lock(int xid, String strData, int lockType) throws DeadlockException { // if any parameter is invalid, then return false if (xid < 0) { return false; } if (strData == null) { return false; } if ((lockType != TrxnObj.READ) && (lockType != TrxnObj.WRITE)) { return false; } // two objects in lock table for easy lookup. TrxnObj trxnObj = new TrxnObj(xid, strData, lockType); DataObj dataObj = new DataObj(xid, strData, lockType); // return true when there is no lock conflict or throw a deadlock exception. try { boolean bConflict = true; BitSet bConvert = new BitSet(1); while (bConflict) { synchronized (this.lockTable) { // check if this lock request conflicts with existing locks bConflict = lockConflict(dataObj, bConvert); if (!bConflict) { // no lock conflict synchronized (this.stampTable) { // remove the timestamp (if any) for this lock request TimeObj timeObj = new TimeObj(xid); this.stampTable.remove(timeObj); } synchronized (this.waitTable) { // remove the entry for this transaction from waitTable (if it // is there) as it has been granted its lock request WaitObj waitObj = new WaitObj(xid, strData, lockType); this.waitTable.remove(waitObj); } if (bConvert.get(0) == true) { // lock conversion // *** ADD CODE HERE *** to carry out the lock conversion in the // lock table System.out.print("Converting lock..."); convertLockTableObj(trxnObj); convertLockTableObj(dataObj); System.out.println("done"); } else { // a lock request that is not lock conversion this.lockTable.add(trxnObj); this.lockTable.add(dataObj); } } } if (bConflict) { // lock conflict exists, wait waitLock(dataObj); } } } catch (DeadlockException deadlock) { throw deadlock; } catch (RedundantLockRequestException redundantlockrequest) { // just ignore the redundant lock request return true; } return true; } /** * Unlocks all data items locked on behalf of the transaction with * id <tt>xid</tt>. * * @param xid Transaction Identifier, should be non-negative. * * @return true if the operation succeeded, false if not. */ public boolean unlockAll(int xid) { // if any parameter is invalid, then return false if (xid < 0) { return false; } TrxnObj trxnQueryObj = new TrxnObj(xid, "", -1); // Only used in elements() call below. synchronized (this.lockTable) { Vector vect = this.lockTable.elements(trxnQueryObj); TrxnObj trxnObj; Vector waitVector; WaitObj waitObj; int size = vect.size(); for (int i = (size - 1); i >= 0; i--) { trxnObj = (TrxnObj) vect.elementAt(i); this.lockTable.remove(trxnObj); DataObj dataObj = new DataObj(trxnObj.getXId(), trxnObj.getDataName(), trxnObj.getLockType()); this.lockTable.remove(dataObj); // check if there are any waiting transactions. synchronized (this.waitTable) { // get all the transactions waiting on this dataObj waitVector = this.waitTable.elements(dataObj); int waitSize = waitVector.size(); for (int j = 0; j < waitSize; j++) { waitObj = (WaitObj) waitVector.elementAt(j); if (waitObj.getLockType() == LockManager.WRITE) { if (j == 0) { // get all other transactions which have locks on the // data item just unlocked. Vector vect1 = this.lockTable.elements(dataObj); // remove interrupted thread from waitTable only if no // other transaction has locked this data item if (vect1.size () == 0) { this.waitTable.remove(waitObj); try { synchronized (waitObj.getThread()) { waitObj.getThread().notify(); } } catch (Exception e) { System.out.println("Exception on unlock\n" + e.getMessage()); } } else { // some other transaction still has a lock on // the data item just unlocked. So, WRITE lock // cannot be granted. break; } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -