Results 1 to 3 of 3
  1. #1
    jon80's Avatar
    jon80 is offline Senior Member
    Join Date
    Feb 2008
    Location
    Malta (EU)
    Posts
    211
    Rep Power
    7

    Default Deadlocks...which threads are locked?

    This program detects deadlocks; the error message reads "Thread-1", does that mean that thread one raised an exception after thread two tried to grab a? Is there a way of knowing this?

    Output:
    thread one grab a
    Waiting For Lock
    Got New Lock
    thread two grab b
    Waiting For Lock
    Got New Lock
    thread one grab b
    Waiting For Lock
    thread two grab a
    Exception in thread "Thread-1" homenetwork.bkr.training.DeadlockDetectedException : DEADLOCK
    at homenetwork.bkr.training.DeadlockDetectingLock.loc k(DeadlockDetectingLock.java:162)
    at homenetwork.bkr.training.DeadlockDetectingLock$2.r un(DeadlockDetectingLock.java:309)
    at java.lang.Thread.run(Unknown Source)
    --- End Program ---

    Java Code:
    package homenetwork.bkr.training;
    
    /*
    Java Threads, 3rd Edition
    By Scott Oaks, Henry Wong
    3rd Edition September 2004 
    ISBN: 0-596-00782-5
    
    (Available at: http://www.java2s.com/Code/Java/Threads/DeadlockDetecting.htm,
    14/06/2009)
    
    Modified after review of warnings generated by Eclipse 3.5.0
    14/06/2009 - JCam.
    
    */
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.concurrent.locks.*;
    
    //
    // This is a very very slow implementation of a ReentrantLock class and is not
    // for
    //   everyday usage. The purpose of this class is to test for deadlocks. The
    // lock()
    //   method now throws a DeadlockDetectedException, if a deadlock occurs.
    //
    @SuppressWarnings("serial")
    public class DeadlockDetectingLock extends ReentrantLock {
      // List of deadlock detecting locks.
      // This array is not thread safe, and must be externally synchronized
      //    by the class lock. Hence, it should only be called by static
      //    methods.
      private static List<DeadlockDetectingLock> deadlockLocksRegistry = new ArrayList();
    
      private static synchronized void registerLock(DeadlockDetectingLock ddl) {
        if (!deadlockLocksRegistry.contains(ddl))
          deadlockLocksRegistry.add(ddl);
      }
    
      @SuppressWarnings("unused")
    private static synchronized void unregisterLock(DeadlockDetectingLock ddl) {
        if (deadlockLocksRegistry.contains(ddl))
          deadlockLocksRegistry.remove(ddl);
      }
    
      // List of threads hard waiting for this lock.
      // This array is not thread safe, and must be externally synchronized
      //    by the class lock. Hence, it should only be called by static
      //    methods.
      private List<Thread> hardwaitingThreads = new ArrayList<Thread>();
    
      private static synchronized void markAsHardwait(List<Thread> l, Thread t) {
        if (!l.contains(t))
          l.add(t);
      }
    
      private static synchronized void freeIfHardwait(List<Thread> l, Thread t) {
        if (l.contains(t))
          l.remove(t);
      }
    
      //
      // Deadlock checking methods
      //
      // Given a thread, return all locks that are already owned
      // Must own class lock prior to calling this method
      private static Iterator<DeadlockDetectingLock> getAllLocksOwned(Thread t) {
        DeadlockDetectingLock current;
        ArrayList<DeadlockDetectingLock> results = new ArrayList<DeadlockDetectingLock>();
    
        Iterator<DeadlockDetectingLock> itr = deadlockLocksRegistry.iterator();
        while (itr.hasNext()) {
          current = (DeadlockDetectingLock) itr.next();
          if (current.getOwner() == t)
            results.add(current);
        }
        return results.iterator();
      }
    
      // Given a lock, return all threads that are hard waiting for the lock
      // Must own class lock prior to calling this method
      private static Iterator<?> getAllThreadsHardwaiting(DeadlockDetectingLock l) {
        return l.hardwaitingThreads.iterator();
      }
    
      // Check to see if a thread can perform a hard wait on a lock
      private static synchronized boolean canThreadWaitOnLock(Thread t,
          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;
      }
    
      //
      // Core Constructors
      //
      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);
      }
    
      //
      // Core Methods
      //
      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");
        }
      }
    
      //
      // Note: It is debatable whether this is a hard or soft wait. Even if
      //       interruption is common, we don't know if the interrupting thread
      //       is also involved in the deadlock. As a compromise, we'll just
      //       not allow interrupts. This method is disabled.
      public void lockInterruptibly() throws InterruptedException {
        lock();
      }
    
      //
      // Note: It is not necessary to override the tryLock() methods. These
      //     methods perform a soft wait -- there is a limit to the wait. It
      //     not possible to deadlock when locks are not waiting indefinitely.
      //
    
      // Note 1: Deadlocks are possible with any hard wait -- this includes
      //      the reacquitition of the lock upon return from an await() method.
      //      As such, condition variables will mark for the future hard
      //      wait, prior to releasing the lock.
      // Note 2: There is no need to check for deadlock on this end because
      //      a deadlock can be created whether the condition variable owns the
      //      lock or is reacquiring it. Since we are marking *before* giving
      //      up ownership, the deadlock will be detected on the lock() side
      //      first. It is not possible to create a new deadlock just by releasing
      //      locks.
      public class DeadlockDetectingCondition implements Condition {
        Condition embedded;
    
        protected DeadlockDetectingCondition(ReentrantLock lock,
            Condition embedded) {
          this.embedded = embedded;
        }
    
        // Note: The algorithm can detect a deadlock condition if the thead is
        //    either waiting for or already owns the lock, or both. This is why
        //    we have to mark for waiting *before* giving up the lock.
        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();
        }
      }
    
      // Return a condition variable that support detection of deadlocks
      public Condition newCondition() {
        return new DeadlockDetectingCondition(this, super.newCondition());
      }
    
      //
      // Testing routines here
      //
      // These are very simple tests -- more tests will have to be written
      private static Lock a = new DeadlockDetectingLock(false, true);
    
      private static Lock b = new DeadlockDetectingLock(false, true);
    
      private static Lock c = new DeadlockDetectingLock(false, true);
    
      @SuppressWarnings("unused")
    private static Condition wa = a.newCondition();
    
      private static Condition wb = b.newCondition();
    
      @SuppressWarnings("unused")
    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(); // 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);
      }
    }
    
    @SuppressWarnings("serial")
    class DeadlockDetectedException extends RuntimeException {
    
        public DeadlockDetectedException(String s) {
            super(s);
        }
    }

  2. #2
    goldest's Avatar
    goldest is offline Senior Member
    Join Date
    Oct 2009
    Location
    Pune, India
    Posts
    469
    Rep Power
    6

    Wink

    And the 4th resurrection of the day...

    Dude, if you keep going with this, moderators will surely take some action.

    Goldest
    Java Is A Funny Language... Really!
    Click on * and add to member reputation, if you find their advices/solutions effective.

  3. #3
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Agree. javabuddy, let's reply to current threads only.

    Edit: all his posts are nothing more than spam for his site. Posts deleted, and javabuddy banned.
    Last edited by Fubarable; 01-06-2011 at 07:16 PM.

Similar Threads

  1. Replies: 0
    Last Post: 03-16-2009, 12:53 AM
  2. Threads + Sockets
    By Tomdarkness in forum New To Java
    Replies: 1
    Last Post: 12-24-2008, 01:06 AM
  3. Threads!
    By rameshraj in forum Advanced Java
    Replies: 1
    Last Post: 05-04-2008, 05:11 PM
  4. Using threads
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 12-11-2007, 11:25 AM
  5. Threads
    By one198 in forum Threads and Synchronization
    Replies: 1
    Last Post: 11-20-2007, 07:15 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •