Methods Summary |
---|
private static void | awaitSeconds(java.util.concurrent.locks.Condition c, int seconds)
try {
c.await(seconds, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
}
|
private static synchronized boolean | canThreadWaitOnLock(java.lang.Thread t, javathreads.examples.ch06.DeadlockDetectingLock l)
Iterator locksOwned = getAllLocksOwned(t);
while (locksOwned.hasNext()) {
DeadlockDetectingLock current = (DeadlockDetectingLock) locksOwned.next();
// Thread can't wait if lock is already owned. This is the end condition
// for the recursive algorithm -- as the initial condition should be
// already tested for.
if (current == l) return false;
Iterator waitingThreads = getAllThreadsHardwaiting(current);
while (waitingThreads.hasNext()) {
Thread otherthread = (Thread) waitingThreads.next();
// In order for the thread to safely wait on the lock, it can't
// own any locks that have waiting threads that already owns
// lock. etc. etc. etc. recursively etc.
if (!canThreadWaitOnLock(otherthread, l)) {
return false;
}
}
}
return true;
|
private static void | delaySeconds(int seconds)
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ex) {
}
|
private static synchronized void | freeIfHardwait(java.util.List l, java.lang.Thread t)
if (l.contains(t)) l.remove(t);
|
private static java.util.Iterator | getAllLocksOwned(java.lang.Thread t)
DeadlockDetectingLock current;
ArrayList results = new ArrayList();
Iterator itr = deadlockLocksRegistry.iterator();
while (itr.hasNext()) {
current = (DeadlockDetectingLock) itr.next();
if (current.getOwner() == t) results.add(current);
}
return results.iterator();
|
private static java.util.Iterator | getAllThreadsHardwaiting(javathreads.examples.ch06.DeadlockDetectingLock l)
return l.hardwaitingThreads.iterator();
|
public void | lock()
// Note: Owner can't change if current thread is owner. It is
// not guaranteed otherwise. Other owners can change due to
// condition variables.
if (isHeldByCurrentThread()) {
if (debugging) System.out.println("Already Own Lock");
super.lock();
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
return;
}
// Note: The wait list must be marked before it is tested because
// there is a race condition between lock() method calls.
markAsHardwait(hardwaitingThreads, Thread.currentThread());
if (canThreadWaitOnLock(Thread.currentThread(), this)) {
if (debugging) System.out.println("Waiting For Lock");
super.lock();
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
if (debugging) System.out.println("Got New Lock");
} else {
throw new DeadlockDetectedException("DEADLOCK");
}
|
public void | lockInterruptibly()
lock();
|
public static void | main(java.lang.String[] args)
int test = 1;
if (args.length > 0)
test = Integer.parseInt(args[0]);
switch(test) {
case 1:
testOne(); // 2 threads deadlocking on grabbing 2 locks
break;
case 2:
testTwo(); // 3 threads deadlocking on grabbing 2 out of 3 locks
break;
case 3:
testThree(); // 2 threads deadlocking on 2 locks with CV wait
break;
default:
System.err.println("usage: java DeadlockDetectingLock [ test# ]");
}
delaySeconds(60);
System.out.println("--- End Program ---");
System.exit(0);
|
private static synchronized void | markAsHardwait(java.util.List l, java.lang.Thread t)
if (!l.contains(t)) l.add(t);
|
public java.util.concurrent.locks.Condition | newCondition()
return new DeadlockDetectingCondition(this, super.newCondition());
|
private static synchronized void | registerLock(javathreads.examples.ch06.DeadlockDetectingLock ddl)
if (!deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.add(ddl);
|
private static void | testOne()
new Thread(new Runnable() {
public void run() {
System.out.println("thread one grab a");
a.lock();
delaySeconds(2);
System.out.println("thread one grab b");
b.lock();
delaySeconds(2);
a.unlock(); b.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("thread two grab b");
b.lock();
delaySeconds(2);
System.out.println("thread two grab a");
a.lock();
delaySeconds(2);
a.unlock(); b.unlock();
}
}).start();
|
private static void | testThree()
new Thread(new Runnable() {
public void run() {
System.out.println("thread one grab b");
b.lock();
System.out.println("thread one grab a");
a.lock();
delaySeconds(2);
System.out.println("thread one waits on b");
awaitSeconds(wb, 10);
a.unlock(); b.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
delaySeconds(1);
System.out.println("thread two grab b");
b.lock();
System.out.println("thread two grab a");
a.lock();
delaySeconds(10);
b.unlock(); c.unlock();
}
}).start();
|
private static void | testTwo()
new Thread(new Runnable() {
public void run() {
System.out.println("thread one grab a");
a.lock();
delaySeconds(2);
System.out.println("thread one grab b");
b.lock();
delaySeconds(10);
a.unlock(); b.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("thread two grab b");
b.lock();
delaySeconds(2);
System.out.println("thread two grab c");
c.lock();
delaySeconds(10);
b.unlock(); c.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("thread three grab c");
c.lock();
delaySeconds(4);
System.out.println("thread three grab a");
a.lock();
delaySeconds(10);
c.unlock(); a.unlock();
}
}).start();
|
private static synchronized void | unregisterLock(javathreads.examples.ch06.DeadlockDetectingLock ddl)
if (deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.remove(ddl);
|