tags:

views:

74

answers:

2

I'm doing some excercises with java (some of you may suppose where the code comes from). I try to provocate a deadlocksituation with the following code:

class Resource {

    public Integer value = 42;
}

public class DeadLockRisk implements Runnable {

    private Resource resourceA = new Resource();
    private Resource resourceB = new Resource();

    public void write(int a, int b) {

        System.out.println(Thread.currentThread().getName() + " try write Lock A");

        synchronized(resourceA) {

            System.out.println(Thread.currentThread().getName() + " write Lock A");
            System.out.println(Thread.currentThread().getName() + " try write Lock B");

            synchronized(resourceB) {

                System.out.println(Thread.currentThread().getName() + " write Lock B");

                resourceA.value = a;
                resourceB.value = b;
     //sit on it!
     //try { Thread.sleep(5000); } catch (Exception e) {}

     System.out.println(Thread.currentThread().getName() + " release write B");
        }
        System.out.println(Thread.currentThread().getName() + " release write A");
    }
    }

    public int read() {

    Integer retVal;
        System.out.println(Thread.currentThread().getName() + " try read Lock B");

        synchronized(resourceB) {

            System.out.println(Thread.currentThread().getName() + " read Lock B");
            System.out.println(Thread.currentThread().getName() + " try read Lock A");

            synchronized(resourceA) {

                System.out.println(Thread.currentThread().getName() + " read Lock A");
                retVal = resourceB.value + resourceA.value;
     System.out.println(Thread.currentThread().getName() + " release read A");
            }
        System.out.println(Thread.currentThread().getName() + " release read B");
        }
    return retVal;
    }

    public void run() {


    if (Thread.currentThread().getName().equals("Thread-1")) {
        write(1,2);
    }

    System.out.println(read());
    }

    public static void main(String[] args) {

        Thread ta = new Thread(new DeadLockRisk());
        Thread tb = new Thread(new DeadLockRisk());
        ta.start(); tb.start();
    }
}

(javac -version javac 1.6.0_0 uname -a Linux inspiron 2.6.29 #1 SMP Sat May 16 10:56:17 CEST 2009 i686 GNU/Linux)

and get (among other situations) the output below:

Thread-1 try write Lock A
Thread-0 try read Lock B
Thread-1 write Lock A      <=====
Thread-0 read Lock B
Thread-1 try write Lock B
Thread-0 try read Lock A
Thread-1 write Lock B
Thread-0 read Lock A       <=====
Thread-1 release write B
Thread-0 release read A
Thread-1 release write A
Thread-0 release read B
Thread-1 try read Lock B
154
Thread-1 read Lock B
Thread-1 try read Lock A
Thread-1 read Lock A
Thread-1 release read A
Thread-1 release read B
3

What do I see wrong? How can Thread-0 even enter the critical section in read() and get the lock on A, before the lock is released by Thread-1. Is this possiby because the output is not synchronous? Deadlock never occures with this code.

+5  A: 

You pass a different instance of DeadLockRisk to both of the threads, so they are not synchronized on the same objects.

Esko Luontola
ups, you're fast, and I am stupid ;-), thanks
@justus.gadient.xyon, if you like this answer, please click on the check icon on the left to select it as 'the answer'
akf
+1  A: 

Both DeadlockRisk instances have different instances for the resourceA and resourceB fields. If you want the code to perform as you expect, change the instance fields to static fields.

Jorn
1 ms, and we have the mess ;-)...java/examples$ java DeadLockRiskThread-0 try read Lock BThread-1 try write Lock AThread-0 read Lock BThread-1 write Lock AThread-0 try read Lock AThread-1 try write Lock B