views:

228

answers:

7

can anyone post a java code that ends up in deadlock??

+2  A: 

Thread DeadLock Example Java Code

Another deadlock demo

rahul
way too difficult, if all you need is a simple deadlock ;)
Jorn
A: 

Create two locks, and two threads that synchronize on them, making sure thread 1 takes lock 1 first and vice versa. Make sure the threads go to sleep for a while after taking the first lock.

public class DeadlockTest {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
     new Thread("1") {
      @Override
      public void run() {
       synchronized (lock1) {
        try {
         Thread.sleep(10);
        } catch (InterruptedException e) {
        }
        synchronized (lock2) {
         System.out.println("1 got em");
        }
       }
      }

     }.start();
     new Thread("2") {
      @Override
      public void run() {
       synchronized (lock2) {
        try {
         Thread.sleep(10);
        } catch (InterruptedException e) {
        }
        synchronized (lock1) {
         System.out.println("2 got em");
        }
       }
      }

     }.start();
    }
}

As you will see, neither "got them" prints will happen.

Jorn
+4  A: 

Here is a nice example:

http://java.sun.com/docs/books/tutorial/essential/concurrency/deadlock.html

bruno conde
A: 

This will cause a deadlock:

public static void main(String[] args) 
{
  final Object object1 = new Object();
  final Object object2 = new Object();

  Thread thread1 = new Thread(
    new Runnable() 
    {
      public void run() 
      {    
        try 
        {    
          //**** Lock on object1 first ****
          synchronized(object1) 
          {    
            Thread.sleep(1000);

            //**** Lock on object2 second ****
            synchronized(object2) 
            {
              System.out.println("Should never get here.");
            }
          }
        }
        catch (InterruptedException e) {}
      }
    }
  );

  Thread thread2 = new Thread(
    new Runnable() 
    {
      public void run() 
      {
        try 
        {
          //**** Lock on object2 first ****
          synchronized(object2) 
          {    
            Thread.sleep(1000);

            //**** Lock on object1 second ****
            synchronized(object1) 
            {
              System.out.println("Should never get here.");
            }
          }
        }
        catch (InterruptedException e) {}
      }
    }
  );

  thread1.start();
  thread2.start();
}
Burkhard
not necessarily ( though most practical schedulers will let thread 2 run some time before thread1 finishes sleeping, it's not guaranteed ) so this is code which is 99.999999999 something % likely to deadlock, rather than code which /will/ deadlock
Pete Kirkham
can you explain the reasoning behind this?
Victor
If your system is very busy when the first Thread.sleep() is called, it's possible that the first thread will resume before the second thread has had a chance to acquire the first lock. The first thread will then acquire the second lock, finish, and allow the second thread to finish as well.
Jorn
A: 

Initialising a semaphore to 0 will always cause deadlock. The reason can be seen on the 1st line of the enter method: "while (value == 0){ this.wait }"

class Semaphore {
    private int value;

    public Semaphore (int init){
        value = init;
    }

    synchronized public void exit() {
        if (value == 0) this.notify();
        ++value;
    }

    synchronized public void enter() throws InterruptedException {
        while (value == 0){
            this.wait();
        }
        --value;
    }
}

class myThread extends Thread{

    Semaphore mutex;

    public myThread(Semaphore s){
        mutex = s;
    }    

    public void run(){
        for(int x=0; x<10;<x++){
            mutex.enter();
            System.out.println(x);
            mutex.exit();
        }
    }
    public static void main(String [ ] args){
        Semaphore s = new Semaphore(0);
        Thread t1 = new myThread(s);
        Thread t2 = new myThread(s);

        t1.start();
        t2.start()
    }


}
chrisbunney
A: 

You can also deadlock with a fixed size thread pool:

final ExecutorService exec = Executors.newFixedThreadPool(1);
exec.submit(new Runnable() {
    public void run() {
       Future<?> f = exec.submit(new Runnable() {
           public void run() {
           }
       });
       try { f.get(); } catch (Exception ex) { }
    }
});
kd304
A: 

As other answers have said, making two threads obtain two locks in the opposite order is one way to cause deadlock (as long as they both hold the first lock before requesting the second). In the code below, the Thread1 obtains lockA and Thread 2 obtains lockB. Once they have both obtained their first lock, they then try to obtain the other thread's lock - but they will deadlock (as the other thread still has that lock).

Instead of using Thread.sleep()s to wait until the first lock has been obtained, which can be slightly unpredictable and make testing harder/slower, you could use a CyclicBarrier to ensure that both threads have obtained their first lock before they attempt to obtain their second (and because they obtain each other's locks in the opposite order, we will guarantee a deadlock):

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Deadlocker {
    private static class Worker implements Runnable {
     private Object firstLock;
     private CyclicBarrier firstLockHeld;
     private Object secondLock;
     public Worker(Object firstLock, CyclicBarrier firstLockHeld, Object secondLock) {
      this.firstLock = firstLock;
      this.firstLockHeld = firstLockHeld;
      this.secondLock = secondLock;
     }

     @Override
     public void run() {
      synchronized (firstLock) {
       try {
        firstLockHeld.await();
       } catch (InterruptedException e) {
        e.printStackTrace(); // Will not happen unless another thread interrupts
       } catch (BrokenBarrierException e) {
        e.printStackTrace(); // Will not happen unless another thread interrupts
       }
       synchronized (secondLock) {
        System.err.println("Should never happen!");
       }
      }
     }
    }

    public static void main(String[] args) {
     CyclicBarrier firstLockHeld = new CyclicBarrier(2);
     Object lockA = new Object();
     Object lockB = new Object();

     new Thread(new Worker(lockA, firstLockHeld, lockB)).start();
     new Thread(new Worker(lockB, firstLockHeld, lockA)).start();
    }
}
paulcm