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;"&gt; deadlockLocksRegistry.iterator();
</span><span style="color: #0000ff;"&gt;while</span><span style="color: #000000;"&gt; (itr.hasNext()) {
  current </span>=<span style="color: #000000;"&gt; (DeadlockDetectingLock) itr.next();
  </span><span style="color: #0000ff;"&gt;if</span> (current.getOwner() ==<span style="color: #000000;"&gt; t)
    results.add(current);
}
</span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; 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;"&gt;//</span><span style="color: #008000;"&gt; Thread can't wait if lock is already owned. This is the end
  </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; condition
  </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;      for the recursive algorithm -- as the initial condition should be
  </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;      already tested for.</span>
  <span style="color: #0000ff;"&gt;if</span> (current ==<span style="color: #000000;"&gt; l)
    </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;false</span><span style="color: #000000;"&gt;;

  Iterator waitingThreads </span>=<span style="color: #000000;"&gt; getAllThreadsHardwaiting(current);
  </span><span style="color: #0000ff;"&gt;while</span><span style="color: #000000;"&gt; (waitingThreads.hasNext()) {
    Thread otherthread </span>=<span style="color: #000000;"&gt; (Thread) waitingThreads.next();

    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; In order for the thread to safely wait on the lock,it can't
    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;   own any locks that have waiting threads that already owns
    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;   lock. etc. etc. etc. recursively etc.</span>
    <span style="color: #0000ff;"&gt;if</span> (!<span style="color: #000000;"&gt;canThreadWaitOnLock(otherthread,l)) {
      </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;false</span><span style="color: #000000;"&gt;;
    }
  }
}
</span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;true</span><span style="color: #000000;"&gt;;

}

<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;"&gt;//</span><span style="color: #008000;"&gt; Note: The wait list must be marked before it is tested because
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;       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;"&gt;protected</span><span style="color: #000000;"&gt; DeadlockDetectingCondition(<a href="https://www.jb51.cc/tag/reentrantlock/" target="_blank" class="keywords">reentrantlock</a> lock,Condition embedded) {
  </span><span style="color: #0000ff;"&gt;this</span>.embedded =<span style="color: #000000;"&gt; embedded;
}

</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; Note: The algorithm can detect a deadlock condition if the thead is
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;    either waiting for or already owns the lock,or both. This is why
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;    we have to mark for waiting *before* giving up the lock.</span>
<span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span> await() <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; InterruptedException {
  </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
    markAsHardwait(hardwaitingThreads,Thread.currentThread());
    embedded.await();
  } </span><span style="color: #0000ff;"&gt;finally</span><span style="color: #000000;"&gt; {
    freeIfHardwait(hardwaitingThreads,Thread.currentThread());
  }
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; awaitUninterruptibly() {
  markAsHardwait(hardwaitingThreads,Thread.currentThread());
  embedded.awaitUninterruptibly();
  freeIfHardwait(hardwaitingThreads,Thread.currentThread());
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;long</span> awaitNanos(<span style="color: #0000ff;"&gt;long</span> nanosTimeout) <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; InterruptedException {
  </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
    markAsHardwait(hardwaitingThreads,Thread.currentThread());
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; embedded.awaitNanos(nanosTimeout);
  } </span><span style="color: #0000ff;"&gt;finally</span><span style="color: #000000;"&gt; {
    freeIfHardwait(hardwaitingThreads,Thread.currentThread());
  }
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;boolean</span> await(<span style="color: #0000ff;"&gt;long</span><span style="color: #000000;"&gt; time,TimeUnit unit)
    </span><span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; InterruptedException {
  </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
    markAsHardwait(hardwaitingThreads,Thread.currentThread());
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; embedded.await(time,unit);
  } </span><span style="color: #0000ff;"&gt;finally</span><span style="color: #000000;"&gt; {
    freeIfHardwait(hardwaitingThreads,Thread.currentThread());
  }
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;boolean</span> awaitUntil(Date deadline) <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; InterruptedException {
  </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
    markAsHardwait(hardwaitingThreads,Thread.currentThread());
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; embedded.awaitUntil(deadline);
  } </span><span style="color: #0000ff;"&gt;finally</span><span style="color: #000000;"&gt; {
    freeIfHardwait(hardwaitingThreads,Thread.currentThread());
  }
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; signal() {
  embedded.signal();
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; 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;"&gt;new</span> Thread(<span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; Runnable() {
  </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; 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;"&gt;);
    b.lock();
    delaySeconds(</span>2<span style="color: #000000;"&gt;);
    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;"&gt;);
    a.lock();
    delaySeconds(</span>2<span style="color: #000000;"&gt;);
    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;"&gt;new</span> Thread(<span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; Runnable() {
  </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; 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;"&gt;);
    b.lock();
    delaySeconds(</span>2<span style="color: #000000;"&gt;);
    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;"&gt;);
    c.lock();
    delaySeconds(</span>10<span style="color: #000000;"&gt;);
    b.unlock();
    c.unlock();
  }
}).start();

</span><span style="color: #0000ff;"&gt;new</span> Thread(<span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; Runnable() {
  </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; 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;"&gt;);
    c.lock();
    delaySeconds(</span>4<span style="color: #000000;"&gt;);
    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;"&gt;);
    a.lock();
    delaySeconds(</span>10<span style="color: #000000;"&gt;);
    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;"&gt;new</span> Thread(<span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; Runnable() {
  </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; run() {
    delaySeconds(</span>1<span style="color: #000000;"&gt;);
    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;"&gt;);
    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;"&gt;);
    a.lock();
    delaySeconds(</span>10<span style="color: #000000;"&gt;);
    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;"&gt;public</span><span style="color: #000000;"&gt; DeadlockDetectedException(String s) {
    </span><span style="color: #0000ff;"&gt;super</span><span style="color: #000000;"&gt;(s);
}

}

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>