can anyone post a java code that ends up in deadlock??
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.
Here is a nice example:
http://java.sun.com/docs/books/tutorial/essential/concurrency/deadlock.html
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();
}
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()
}
}
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) { }
}
});
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();
}
}