Deadlock detecting — turn
<span style="color: #008000;">/
<span style="color: #0000ff;">import java.util.<span style="color: #000000;">;
<span style="color: #0000ff;">import java.util.concurrent.<span style="color: #000000;">;
<span style="color: #0000ff;">import java.util.concurrent.locks.<span style="color: #000000;">;<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> This is a very very slow implementation of a reentrantlock class and is not
<span style="color: #008000;">//<span style="color: #008000;"> for
<span style="color: #008000;">//<span style="color: #008000;"> everyday usage. The purpose of this class is to test for deadlocks. The
<span style="color: #008000;">//<span style="color: #008000;"> lock()
<span style="color: #008000;">//<span style="color: #008000;"> method Now throws a DeadlockDetectedException,if a deadlock occurs.
<span style="color: #008000;">//
<span style="color: #0000ff;">public <span style="color: #0000ff;">class DeadlockDetectingLock <span style="color: #0000ff;">extends<span style="color: #000000;"> reentrantlock {
<span style="color: #008000;">//<span style="color: #008000;"> List of deadlock detecting locks.
<span style="color: #008000;">//<span style="color: #008000;"> This array is not thread safe,and must be externally synchronized
<span style="color: #008000;">//<span style="color: #008000;"> by the class lock. Hence,it should only be called by static
<span style="color: #008000;">//<span style="color: #008000;"> methods.
<span style="color: #0000ff;">private <span style="color: #0000ff;">static List deadlockLocksRegistry = <span style="color: #0000ff;">new<span style="color: #000000;"> ArrayList();<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">synchronized <span style="color: #0000ff;">void<span style="color: #000000;"> registerLock(DeadlockDetectingLock ddl) {
<span style="color: #0000ff;">if (!<span style="color: #000000;">deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.add(ddl);
}<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">synchronized <span style="color: #0000ff;">void<span style="color: #000000;"> unregisterLock(DeadlockDetectingLock ddl) {
<span style="color: #0000ff;">if<span style="color: #000000;"> (deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.remove(ddl);
}<span style="color: #008000;">//<span style="color: #008000;"> List of threads hard waiting for this lock.
<span style="color: #008000;">//<span style="color: #008000;"> This array is not thread safe,it should only be called by static
<span style="color: #008000;">//<span style="color: #008000;"> methods.
<span style="color: #0000ff;">private List hardwaitingThreads = <span style="color: #0000ff;">new<span style="color: #000000;"> ArrayList();<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">synchronized <span style="color: #0000ff;">void<span style="color: #000000;"> markAsHardwait(List l,Thread t) {
<span style="color: #0000ff;">if (!<span style="color: #000000;">l.contains(t))
l.add(t);
}<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">synchronized <span style="color: #0000ff;">void<span style="color: #000000;"> freeIfHardwait(List l,Thread t) {
<span style="color: #0000ff;">if<span style="color: #000000;"> (l.contains(t))
l.remove(t);
}<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Deadlock checking methods
<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Given a thread,return all locks that are already owned
<span style="color: #008000;">//<span style="color: #008000;"> Must own class lock prior to calling this method
<span style="color: #0000ff;">private <span style="color: #0000ff;">static<span style="color: #000000;"> Iterator getAllLocksOwned(Thread t) {
DeadlockDetectingLock current;
ArrayList results = <span style="color: #0000ff;">new<span style="color: #000000;"> ArrayList();Iterator itr </span>=<span style="color: #000000;"> deadlockLocksRegistry.iterator(); </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (itr.hasNext()) { current </span>=<span style="color: #000000;"> (DeadlockDetectingLock) itr.next(); </span><span style="color: #0000ff;">if</span> (current.getOwner() ==<span style="color: #000000;"> t) results.add(current); } </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> results.iterator();
}
<span style="color: #008000;">//<span style="color: #008000;"> Given a lock,return all threads that are hard waiting for the lock
<span style="color: #008000;">//<span style="color: #008000;"> Must own class lock prior to calling this method
<span style="color: #0000ff;">private <span style="color: #0000ff;">static<span style="color: #000000;"> Iterator getAllThreadsHardwaiting(DeadlockDetectingLock l) {
<span style="color: #0000ff;">return<span style="color: #000000;"> l.hardwaitingThreads.iterator();
}<span style="color: #008000;">//<span style="color: #008000;"> Check to see if a thread can perform a hard wait on a lock
<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">synchronized <span style="color: #0000ff;">boolean<span style="color: #000000;"> canThreadWaitOnLock(Thread t,DeadlockDetectingLock l) {
Iterator locksOwned =<span style="color: #000000;"> getAllLocksOwned(t);
<span style="color: #0000ff;">while<span style="color: #000000;"> (locksOwned.hasNext()) {
DeadlockDetectingLock current =<span style="color: #000000;"> (DeadlockDetectingLock) locksOwned
.next();</span><span style="color: #008000;">//</span><span style="color: #008000;"> Thread can't wait if lock is already owned. This is the end </span><span style="color: #008000;">//</span><span style="color: #008000;"> condition </span><span style="color: #008000;">//</span><span style="color: #008000;"> for the recursive algorithm -- as the initial condition should be </span><span style="color: #008000;">//</span><span style="color: #008000;"> already tested for.</span> <span style="color: #0000ff;">if</span> (current ==<span style="color: #000000;"> l) </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">; Iterator waitingThreads </span>=<span style="color: #000000;"> getAllThreadsHardwaiting(current); </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (waitingThreads.hasNext()) { Thread otherthread </span>=<span style="color: #000000;"> (Thread) waitingThreads.next(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> In order for the thread to safely wait on the lock,it can't </span><span style="color: #008000;">//</span><span style="color: #008000;"> own any locks that have waiting threads that already owns </span><span style="color: #008000;">//</span><span style="color: #008000;"> lock. etc. etc. etc. recursively etc.</span> <span style="color: #0000ff;">if</span> (!<span style="color: #000000;">canThreadWaitOnLock(otherthread,l)) { </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">; } } } </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
}
<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Core Constructors
<span style="color: #008000;">//
<span style="color: #0000ff;">public<span style="color: #000000;"> DeadlockDetectingLock() {
<span style="color: #0000ff;">this(<span style="color: #0000ff;">false,<span style="color: #0000ff;">false<span style="color: #000000;">);
}<span style="color: #0000ff;">public DeadlockDetectingLock(<span style="color: #0000ff;">boolean<span style="color: #000000;"> fair) {
<span style="color: #0000ff;">this(fair,<span style="color: #0000ff;">false<span style="color: #000000;">);
}<span style="color: #0000ff;">private <span style="color: #0000ff;">boolean<span style="color: #000000;"> debugging;
<span style="color: #0000ff;">public DeadlockDetectingLock(<span style="color: #0000ff;">boolean fair,<span style="color: #0000ff;">boolean<span style="color: #000000;"> debug) {
<span style="color: #0000ff;">super<span style="color: #000000;">(fair);
debugging =<span style="color: #000000;"> debug;
registerLock(<span style="color: #0000ff;">this<span style="color: #000000;">);
}<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Core Methods
<span style="color: #008000;">//
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> lock() {
<span style="color: #008000;">//<span style="color: #008000;"> Note: Owner can't change if current thread is owner. It is
<span style="color: #008000;">//<span style="color: #008000;"> not guaranteed otherwise. Other owners can change due to
<span style="color: #008000;">//<span style="color: #008000;"> condition variables.
<span style="color: #0000ff;">if<span style="color: #000000;"> (isHeldByCurrentThread()) {
<span style="color: #0000ff;">if<span style="color: #000000;"> (debugging)
System.out.println("Already Own Lock"<span style="color: #000000;">);
<span style="color: #0000ff;">super<span style="color: #000000;">.lock();
freeIfHardwait(hardwaitingThreads,Thread.currentThread());
<span style="color: #0000ff;">return<span style="color: #000000;">;
}</span><span style="color: #008000;">//</span><span style="color: #008000;"> Note: The wait list must be marked before it is tested because </span><span style="color: #008000;">//</span><span style="color: #008000;"> there is a race condition between lock() method calls.</span>
<span style="color: #000000;"> markAsHardwait(hardwaitingThreads,Thread.currentThread());
<span style="color: #0000ff;">if (canThreadWaitOnLock(Thread.currentThread(),<span style="color: #0000ff;">this<span style="color: #000000;">)) {
<span style="color: #0000ff;">if<span style="color: #000000;"> (debugging)
System.out.println("Waiting For Lock"<span style="color: #000000;">);
<span style="color: #0000ff;">super<span style="color: #000000;">.lock();
freeIfHardwait(hardwaitingThreads,Thread.currentThread());
<span style="color: #0000ff;">if<span style="color: #000000;"> (debugging)
System.out.println("Got New Lock"<span style="color: #000000;">);
} <span style="color: #0000ff;">else<span style="color: #000000;"> {
<span style="color: #0000ff;">throw <span style="color: #0000ff;">new DeadlockDetectedException("DEADLOCK"<span style="color: #000000;">);
}
}<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Note: It is debatable whether this is a hard or soft wait. Even if
<span style="color: #008000;">//<span style="color: #008000;"> interruption is common,we don't kNow if the interrupting thread
<span style="color: #008000;">//<span style="color: #008000;"> is also involved in the deadlock. As a compromise,we'll just
<span style="color: #008000;">//<span style="color: #008000;"> not allow interrupts. This method is disabled.
<span style="color: #0000ff;">public <span style="color: #0000ff;">void lockInterruptibly() <span style="color: #0000ff;">throws<span style="color: #000000;"> InterruptedException {
lock();
}<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Note: It is not necessary to override the tryLock() methods. These
<span style="color: #008000;">//<span style="color: #008000;"> methods perform a soft wait -- there is a limit to the wait. It
<span style="color: #008000;">//<span style="color: #008000;"> not possible to deadlock when locks are not waiting indefinitely.
<span style="color: #008000;">//<span style="color: #008000;">//<span style="color: #008000;"> Note 1: Deadlocks are possible with any hard wait -- this includes
<span style="color: #008000;">//<span style="color: #008000;"> the reacquitition of the lock upon return from an await() method.
<span style="color: #008000;">//<span style="color: #008000;"> As such,condition variables will mark for the future hard
<span style="color: #008000;">//<span style="color: #008000;"> wait,prior to releasing the lock.
<span style="color: #008000;">//<span style="color: #008000;"> Note 2: There is no need to check for deadlock on this end because
<span style="color: #008000;">//<span style="color: #008000;"> a deadlock can be created whether the condition variable owns the
<span style="color: #008000;">//<span style="color: #008000;"> lock or is reacquiring it. Since we are marking before giving
<span style="color: #008000;">//<span style="color: #008000;"> up ownership,the deadlock will be detected on the lock() side
<span style="color: #008000;">//<span style="color: #008000;"> first. It is not possible to create a new deadlock just by releasing
<span style="color: #008000;">//<span style="color: #008000;"> locks.
<span style="color: #0000ff;">public <span style="color: #0000ff;">class DeadlockDetectingCondition <span style="color: #0000ff;">implements<span style="color: #000000;"> Condition {
Condition embedded;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;"> DeadlockDetectingCondition(<a href="https://www.jb51.cc/tag/reentrantlock/" target="_blank" class="keywords">reentrantlock</a> lock,Condition embedded) { </span><span style="color: #0000ff;">this</span>.embedded =<span style="color: #000000;"> embedded; } </span><span style="color: #008000;">//</span><span style="color: #008000;"> Note: The algorithm can detect a deadlock condition if the thead is </span><span style="color: #008000;">//</span><span style="color: #008000;"> either waiting for or already owns the lock,or both. This is why </span><span style="color: #008000;">//</span><span style="color: #008000;"> we have to mark for waiting *before* giving up the lock.</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> await() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> InterruptedException { </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { markAsHardwait(hardwaitingThreads,Thread.currentThread()); embedded.await(); } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> { freeIfHardwait(hardwaitingThreads,Thread.currentThread()); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> awaitUninterruptibly() { markAsHardwait(hardwaitingThreads,Thread.currentThread()); embedded.awaitUninterruptibly(); freeIfHardwait(hardwaitingThreads,Thread.currentThread()); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">long</span> awaitNanos(<span style="color: #0000ff;">long</span> nanosTimeout) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> InterruptedException { </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { markAsHardwait(hardwaitingThreads,Thread.currentThread()); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> embedded.awaitNanos(nanosTimeout); } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> { freeIfHardwait(hardwaitingThreads,Thread.currentThread()); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span> await(<span style="color: #0000ff;">long</span><span style="color: #000000;"> time,TimeUnit unit) </span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> InterruptedException { </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { markAsHardwait(hardwaitingThreads,Thread.currentThread()); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> embedded.await(time,unit); } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> { freeIfHardwait(hardwaitingThreads,Thread.currentThread()); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span> awaitUntil(Date deadline) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> InterruptedException { </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { markAsHardwait(hardwaitingThreads,Thread.currentThread()); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> embedded.awaitUntil(deadline); } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> { freeIfHardwait(hardwaitingThreads,Thread.currentThread()); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> signal() { embedded.signal(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> signalAll() { embedded.signalAll(); }
}
<span style="color: #008000;">//<span style="color: #008000;"> Return a condition variable that support detection of deadlocks
<span style="color: #0000ff;">public<span style="color: #000000;"> Condition newCondition() {
<span style="color: #0000ff;">return <span style="color: #0000ff;">new DeadlockDetectingCondition(<span style="color: #0000ff;">this,<span style="color: #0000ff;">super<span style="color: #000000;">.newCondition());
}<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> Testing routines here
<span style="color: #008000;">//
<span style="color: #008000;">//<span style="color: #008000;"> These are very simple tests -- more tests will have to be written
<span style="color: #0000ff;">private <span style="color: #0000ff;">static Lock a = <span style="color: #0000ff;">new DeadlockDetectingLock(<span style="color: #0000ff;">false,<span style="color: #0000ff;">true<span style="color: #000000;">);<span style="color: #0000ff;">private <span style="color: #0000ff;">static Lock b = <span style="color: #0000ff;">new DeadlockDetectingLock(<span style="color: #0000ff;">false,<span style="color: #0000ff;">true<span style="color: #000000;">);
<span style="color: #0000ff;">private <span style="color: #0000ff;">static Lock c = <span style="color: #0000ff;">new DeadlockDetectingLock(<span style="color: #0000ff;">false,<span style="color: #0000ff;">true<span style="color: #000000;">);
<span style="color: #0000ff;">private <span style="color: #0000ff;">static Condition wa =<span style="color: #000000;"> a.newCondition();
<span style="color: #0000ff;">private <span style="color: #0000ff;">static Condition wb =<span style="color: #000000;"> b.newCondition();
<span style="color: #0000ff;">private <span style="color: #0000ff;">static Condition wc =<span style="color: #000000;"> c.newCondition();
<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">void delaySeconds(<span style="color: #0000ff;">int<span style="color: #000000;"> seconds) {
<span style="color: #0000ff;">try<span style="color: #000000;"> {
Thread.sleep(seconds * 1000<span style="color: #000000;">);
} <span style="color: #0000ff;">catch<span style="color: #000000;"> (InterruptedException ex) {
}
}<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">void awaitSeconds(Condition c,<span style="color: #0000ff;">int<span style="color: #000000;"> seconds) {
<span style="color: #0000ff;">try<span style="color: #000000;"> {
c.await(seconds,TimeUnit.SECONDS);
} <span style="color: #0000ff;">catch<span style="color: #000000;"> (InterruptedException ex) {
}
}<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> testOne() {
<span style="color: #0000ff;">new Thread(<span style="color: #0000ff;">new<span style="color: #000000;"> Runnable() {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> run() {
System.out.println("thread one grab a"<span style="color: #000000;">);
a.lock();
delaySeconds(2<span style="color: #000000;">);
System.out.println("thread one grab b"<span style="color: #000000;">);
b.lock();
delaySeconds(2<span style="color: #000000;">);
a.unlock();
b.unlock();
}
}).start();</span><span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Runnable() { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread two grab b"<span style="color: #000000;">); b.lock(); delaySeconds(</span>2<span style="color: #000000;">); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread two grab a"<span style="color: #000000;">); a.lock(); delaySeconds(</span>2<span style="color: #000000;">); a.unlock(); b.unlock(); } }).start();
}
<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> testTwo() {
<span style="color: #0000ff;">new Thread(<span style="color: #0000ff;">new<span style="color: #000000;"> Runnable() {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> run() {
System.out.println("thread one grab a"<span style="color: #000000;">);
a.lock();
delaySeconds(2<span style="color: #000000;">);
System.out.println("thread one grab b"<span style="color: #000000;">);
b.lock();
delaySeconds(10<span style="color: #000000;">);
a.unlock();
b.unlock();
}
}).start();</span><span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Runnable() { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread two grab b"<span style="color: #000000;">); b.lock(); delaySeconds(</span>2<span style="color: #000000;">); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread two grab c"<span style="color: #000000;">); c.lock(); delaySeconds(</span>10<span style="color: #000000;">); b.unlock(); c.unlock(); } }).start(); </span><span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Runnable() { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread three grab c"<span style="color: #000000;">); c.lock(); delaySeconds(</span>4<span style="color: #000000;">); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread three grab a"<span style="color: #000000;">); a.lock(); delaySeconds(</span>10<span style="color: #000000;">); c.unlock(); a.unlock(); } }).start();
}
<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> testThree() {
<span style="color: #0000ff;">new Thread(<span style="color: #0000ff;">new<span style="color: #000000;"> Runnable() {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> run() {
System.out.println("thread one grab b"<span style="color: #000000;">);
b.lock();
System.out.println("thread one grab a"<span style="color: #000000;">);
a.lock();
delaySeconds(2<span style="color: #000000;">);
System.out.println("thread one waits on b"<span style="color: #000000;">);
awaitSeconds(wb,10<span style="color: #000000;">);
a.unlock();
b.unlock();
}
}).start();</span><span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Runnable() { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { delaySeconds(</span>1<span style="color: #000000;">); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread two grab b"<span style="color: #000000;">); b.lock(); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" class="keywords">stem</a>.out.println(</span>"thread two grab a"<span style="color: #000000;">); a.lock(); delaySeconds(</span>10<span style="color: #000000;">); b.unlock(); c.unlock(); } }).start();
}
<span style="color: #0000ff;">public <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> main(String args[]) {
<span style="color: #0000ff;">int test = 1<span style="color: #000000;">;
<span style="color: #0000ff;">if (args.length > 0<span style="color: #000000;">)
test = Integer.parseInt(args[0<span style="color: #000000;">]);
<span style="color: #0000ff;">switch<span style="color: #000000;"> (test) {
<span style="color: #0000ff;">case 1<span style="color: #000000;">:
testOne(); <span style="color: #008000;">//<span style="color: #008000;"> 2 threads deadlocking on grabbing 2 locks
<span style="color: #0000ff;">break<span style="color: #000000;">;
<span style="color: #0000ff;">case 2<span style="color: #000000;">:
testTwo(); <span style="color: #008000;">//<span style="color: #008000;"> 3 threads deadlocking on grabbing 2 out of 3 locks
<span style="color: #0000ff;">break<span style="color: #000000;">;
<span style="color: #0000ff;">case 3<span style="color: #000000;">:
testThree(); <span style="color: #008000;">//<span style="color: #008000;"> 2 threads deadlocking on 2 locks with CV wait
<span style="color: #0000ff;">break<span style="color: #000000;">;
<span style="color: #0000ff;">default<span style="color: #000000;">:
System.err.println("usage: java DeadlockDetectingLock [ test# ]"<span style="color: #000000;">);
}
delaySeconds(60<span style="color: #000000;">);
System.out.println("--- End Program ---"<span style="color: #000000;">);
System.exit(0<span style="color: #000000;">);
}
}<span style="color: #0000ff;">class DeadlockDetectedException <span style="color: #0000ff;">extends<span style="color: #000000;"> RuntimeException {
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> DeadlockDetectedException(String s) { </span><span style="color: #0000ff;">super</span><span style="color: #000000;">(s); }
}