Solving Deadlock
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class DeadlockDetectingLock extends
ReentrantLock
{
private static List deadlockLocksRegistry = new ArrayList();
private static synchronized void
registerLock(DeadlockDetectingLock ddl)
{
if
(!deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.add(ddl);
}
private static synchronized void unregisterLock(DeadlockDetectingLock
ddl)
{
if
(deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.remove(ddl);
}
private List hardwaitingThreads = new ArrayList();
private static synchronized void markAsHardwait(List l, Thread t)
{
if
(!l.contains(t))
l.add(t);
}
private static synchronized void
freeIfHardwait(List l, Thread t)
{
if
(l.contains(t))
l.remove(t);
}
private static Iterator
getAllLocksOwned(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 Iterator
getAllThreadsHardwaiting(DeadlockDetectingLock
l) {
return l.hardwaitingThreads.iterator();
}
private static synchronized boolean
canThreadWaitOnLock
(Thread t,DeadlockDetectingLock l)
{
Iterator locksOwned = getAllLocksOwned(t);
while
(locksOwned.hasNext())
{
DeadlockDetectingLock
current = (DeadlockDetectingLock)
locksOwned.next();
if
(current == l)
return false;
Iterator waitingThreads = getAllThreadsHardwaiting(current);
while (waitingThreads.hasNext())
{
Thread otherthread = (Thread) waitingThreads.next();
if (!canThreadWaitOnLock(otherthread, l))
{
return false;
}
}
}
return true;
}
public DeadlockDetectingLock()
{
this(false, false);
}
public DeadlockDetectingLock(boolean fair)
{
this(fair, false);
}
private boolean debugging;
public DeadlockDetectingLock(boolean fair,
boolean debug)
{
super(fair);
debugging = debug;
registerLock(this);
}
public void lock()
{
if
(isHeldByCurrentThread())
{
if
(debugging)
System.out.println("Already Own Lock");
super.lock();
freeIfHardwait(hardwaitingThreads,
Thread.currentThread());
return;
}
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() throws
InterruptedException
{
lock();
}
public class DeadlockDetectingCondition
implements Condition
{
Condition embedded;
protected DeadlockDetectingCondition(ReentrantLock lock,
Condition embedded)
{
this.embedded = embedded;
}
Public void await() throws InterruptedException
{
try
{
markAsHardwait(hardwaitingThreads, Thread.currentThread());
embedded.await();
}
finally
{
freeIfHardwait(hardwaitingThreads,
Thread.currentThread());
}
}
public void awaitUninterruptibly()
{
markAsHardwait(hardwaitingThreads,
Thread.currentThread());
embedded.awaitUninterruptibly();
freeIfHardwait(hardwaitingThreads,
Thread.currentThread());
}
public long awaitNanos(long nanosTimeout) throws InterruptedException
{
try
{
markAsHardwait(hardwaitingThreads,
Thread.currentThread());
return embedded.awaitNanos(nanosTimeout);
}
finally
{
freeIfHardwait(hardwaitingThreads,
Thread.currentThread());
}
}
public boolean await(long time, TimeUnit unit)throws
InterruptedException
{
try
{
markAsHardwait(hardwaitingThreads,
Thread.currentThread());
return embedded.await(time, unit);
}
finally
{
freeIfHardwait(hardwaitingThreads,
Thread.currentThread());
}
}
public boolean awaitUntil(Date
deadline) throws InterruptedException
{
try
{
markAsHardwait(hardwaitingThreads,
Thread.currentThread());
return embedded.awaitUntil(deadline);
}
finally
{
freeIfHardwait(hardwaitingThreads,
Thread.currentThread());
}
}
public void signal()
{
embedded.signal();
}
public void signalAll()
{
embedded.signalAll();
}
}
public Condition newCondition()
{
return new DeadlockDetectingCondition(this,
super.newCondition());
}
private static Lock a = new
DeadlockDetectingLock(false, true);
private static Lock b = new
DeadlockDetectingLock(false, true);
private static Lock c = new
DeadlockDetectingLock(false, true);
private static Condition wa =
a.newCondition();
private static Condition wb =
b.newCondition();
private static Condition wc =
c.newCondition();
private static void delaySeconds(int seconds)
{
try
{
Thread.sleep(seconds * 1000);
}
catch
(InterruptedException ex)
{
}
}
private static void awaitSeconds(Condition c,
int seconds)
{
try
{
c.await(seconds, TimeUnit.Seconds);
}
catch
(InterruptedException ex) {}
}
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 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 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();
}
public static void main(String args[])
{
int
test = 1;
if
(args.length > 0)
test
= Integer.parseInt(args[0]);
switch (test)
{
case 1:
testOne();
break;
case 2:
testTwo();
break;
case 3:
testThree();
break;
default:
System.err.println("usage: java
DeadlockDetectingLock [ test# ]");
}
delaySeconds(60);
System.out.println("--- End Program ---");
System.exit(0);
}
}
class DeadlockDetectedException extends
RuntimeException
{
public DeadlockDetectedException(String s)
{
super(s);
}
}
No comments:
Post a Comment