Monday, March 9, 2015

Solving Deadlock in Java program



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();
}
locks.
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