📄 lockcontrol.java
字号:
} while (++index < endIndex); } if (lockItem != null) { if (SanityManager.DEBUG) { if (!grantLock) { SanityManager.THROWASSERT("lock is not granted !" + lockItem); } } // we already held a lock of this type, just bump the lock count lockItem.count++; return lockItem; } if (grantLock) { lockItem = new Lock(compatabilitySpace, lref, qualifier); grant(lockItem); return lockItem; } ActiveLock waitingLock = new ActiveLock(compatabilitySpace, lref, qualifier); // If the object is already locked by this compatability space // then this lock can be granted by skipping other waiters. if (spaceHasALock) { waitingLock.canSkip = true; } if (waiting == null) waiting = new java.util.LinkedList(); // Add lock to the waiting list addWaiter(waiting, waitingLock, ls); if (waitingLock.canSkip) { lastPossibleSkip = waitingLock; } return waitingLock; } protected boolean isUnlocked() { // If firstGrant is set then this object is locked if (firstGrant != null) return false; List lgranted = granted; return (lgranted == null) || lgranted.isEmpty(); } /** Return the first lock in the wait line, null if the line is empty. */ public ActiveLock firstWaiter() { if ((waiting == null) || waiting.isEmpty()) return null; return (ActiveLock) waiting.get(0); } /** Get the next waiting lock (if any). */ ActiveLock getNextWaiter(ActiveLock item, boolean remove, LockSet ls) { ActiveLock nextWaitingLock = null; if (remove && (waiting.get(0) == item)) { // item is at the head of the list and being removed, // always return the next waiter popFrontWaiter(waiting, ls); nextWaitingLock = firstWaiter(); } else if ((lastPossibleSkip != null) && (lastPossibleSkip != item)) { // there are potential locks that could be granted // and the last one is not the lock we just looked at. // need to find the first lock after the one passed // in that has the canSkip flag set. int itemIndex = waiting.indexOf(item); int removeIndex = remove ? itemIndex : -1; // skip the entry we just looked at. /*List*/ // dli.advance(); // for (; !dli.atEnd(); dli.advance()) { if (itemIndex != waiting.size() - 1) { for (ListIterator li = waiting.listIterator(itemIndex + 1); li.hasNext();) { //ActiveLock al = (ActiveLock) dli.get(); ActiveLock al = (ActiveLock) li.next(); if (al.canSkip) { nextWaitingLock = al; break; } } } if (remove) { removeWaiter(waiting, removeIndex, ls); } } else { if (remove) { int count = removeWaiter(waiting, item, ls); if (SanityManager.DEBUG) { if (count != 1) { SanityManager.THROWASSERT( "count = " + count + "item = " + item + "waiting = " + waiting); } } } } if (remove && (item == lastPossibleSkip)) lastPossibleSkip = null; if (nextWaitingLock != null) { if (!nextWaitingLock.setPotentiallyGranted()) nextWaitingLock = null; } return nextWaitingLock; } /** Return the lockable object controlled by me. */ public Lockable getLockable() { return ref; } public Lock getFirstGrant() { return firstGrant; } public List getGranted() { return granted; } public List getWaiting() { return waiting; } /** Give up waiting up on a lock */ protected void giveUpWait(Object item, LockSet ls) { int count = removeWaiter(waiting, item, ls); if (item == lastPossibleSkip) lastPossibleSkip = null; if (SanityManager.DEBUG) { if (count != 1) { SanityManager.THROWASSERT( "count = " + count + "item = " + item + "waiting = " + waiting); } } } /* ** Deadlock support. */ /** Add the waiters of this lock into this Dictionary object. <BR> Each waiting thread gets two entries in the hashtable <OL> <LI>key=compatibility space - value=ActiveLock <LI>key=ActiveLock - value={LockControl for first waiter|ActiveLock of previosue waiter} </OL> */ public void addWaiters(Dictionary waiters) { if ((waiting == null) || waiting.isEmpty()) return; Object previous = this; for (ListIterator li = waiting.listIterator(); li.hasNext(); ) { ActiveLock waitingLock = ((ActiveLock) li.next()); Object waiter = waitingLock.getCompatabilitySpace(); waiters.put(waiter, waitingLock); waiters.put(waitingLock, previous); previous = waitingLock; } } /** Return a Stack of the held locks (Lock objects) on this Lockable. */ List getGrants() { List ret; if (firstGrant != null) { ret = new java.util.LinkedList(); ret.add(firstGrant); } else { ret = new java.util.LinkedList(granted); } return ret; } /** Find a granted lock matching this space and qualifier */ public final Lock getLock(Object compatabilitySpace, Object qualifier) { if (isUnlocked()) return null; List lgranted = granted; int index = 0; int endIndex = firstGrant == null ? lgranted.size() : 0; do { Lock gl = firstGrant == null ? (Lock) lgranted.get(index) : firstGrant; if (!gl.getCompatabilitySpace().equals(compatabilitySpace)) continue; if (gl.getQualifier() == qualifier) return gl; } while (++index < endIndex); return null; }//EXCLUDE-START-lockdiag- /** * make a shallow clone of myself */ /* package */ public Control shallowClone() { return new LockControl(this); }//EXCLUDE-END-lockdiag- /** * Add a lock request to a list of waiters. * * @param waiting The list of waiters to add to * @param lockItem The lock request * @param ls The LockSet */ private void addWaiter(List waiting, Lock lockItem, LockSet ls) { // Add lock to the waiting list waiting.add(lockItem); // Maintain count of waiters ls.oneMoreWaiter(); } /** * Remove and return the first lock request from a list of waiters. * * @param waiting The list of waiters to pop from * @param ls The LockSet * * @return The removed lock request */ private Object popFrontWaiter(List waiting, LockSet ls) { // Maintain count of waiters ls.oneLessWaiter(); // Remove and return the first lock request return waiting.remove(0); } /** * Remove and return the lock request at the given index * from a list of waiters. * * @param waiting The list of waiters to pop from * @param index The index at which to remove the lock request * @param ls The LockSet * * @return The removed lock request */ private Object removeWaiter(List waiting, int index, LockSet ls) { // Maintain count of waiters ls.oneLessWaiter(); // Remove and return the first lock request return waiting.remove(index); } /** * Remove and return the given lock request from a list of waiters. * * @param waiting The list of waiters to pop from * @param item The item to remove * @param ls The LockSet * * @return The number of items removed */ private int removeWaiter(List waiting, Object item, LockSet ls) { // Maintain count of waiters ls.oneLessWaiter(); // Remove item and return number of items removed return waiting.remove(item) ? 1 : 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -