gipsy
gipsy

Reputation: 3859

Simulating Java thread dead lock

Is it possible simulate Java dead lock scenario with just one object shared between multiple threads?

For example I have a class

public class MyClass {

    public synchronized void syncInstanceMethod1(){
        /// Anything here to simulate a dead lock

    }
    public synchronized void syncInstanceMethod2(){
        /// Anything here to simulate a dead lock
    }
    public static synchronized void syncStaticMethod1(){
        /// Anything here to simulate a dead lock
    }
    public static synchronized void syncStaticMethod2(){
        /// Anything here to simulate a dead lock
    }

    public void instanceMethod1(){
        /// Anything here to simulate a dead lock
    }

    public void instanceMethod2(){
        /// Anything here to simulate a dead lock
    }


    public static void main(String[] args) {
        MyClass shared = new MyClass();  // Allowed to create only one instance

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {

                // Do whatever here to simulate dead lock like calling various methods on the shared object in any order

            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {

                // Do whatever here to simulate dead lock like calling various methods on the shared object in any order

            }
        });

        // Allowed to create more threads like above. t3 , t4 etc...

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

}

May be it is impossible. As the common situation where a dead lock can occur is a code block where it acquire lock one one object and without releasing it try to acquire lock on another object.

We can simulate this situation from one of the synchronized instance method by calling a static synchronized method i.e trying to lock the 'class' object while holding lock on 'this'. But for a deadlock to occur we need the similar situation in the reverse order elsewhere.

Also , as a static method cannot access 'this' it cannot lock 'this' and two synchronized instance method cannot run at the same time , these things making believe that we cannot simulate a dead lock here. Am I correct?

Upvotes: 1

Views: 747

Answers (2)

NESPowerGlove
NESPowerGlove

Reputation: 5496

I misread your question when I first read it. But if the shared instance isn't in scope in your static synchronized method (like a reference with a static variable) then you won't be able to lock first on static and then on the shared instance, as it's not in scope, can't lock or call it.

I guess I don't know what's allowed in your assignment though, that is a bit confusing.

Upvotes: 1

Ravi K Thapliyal
Ravi K Thapliyal

Reputation: 51721

Although, you've been asked to create just one instance, the threads still have two locks to contend for. Instance methods would require a thread to acquire the lock on the MyClass object instance i.e. shared or this depending on how you look at it.

Static methods on the other hand would require a thread to acquire a lock on the MyClass.class class object instance; the one you get from this.getClass().

So, if Thread A is already executing a synchronized instance method (has a lock on this) and tries to get into one of the synchronized static methods, while another Thread B is also already executing a static method (has a lock on MyClass.class) and now tries to enter a synchronized instance method on the same MyClass object, a deadlock will occur.

Here's some code that simulates this scenario.

public class SingleObjectDeadlock {

    public synchronized void syncInstanceMethod1() {
        System.out.println("In syncInstanceMethod1()");
        syncStaticMethod2();
    }

    public synchronized void syncInstanceMethod2() {
        System.out.println("In syncInstanceMethod2()");
    }

    public static synchronized void syncStaticMethod1(SingleObjectDeadlock shared) {
        System.out.println("In syncStaticMethod1()");
        shared.syncInstanceMethod2();
    }

    public static synchronized void syncStaticMethod2() {
        System.out.println("In syncStaticMethod2()");
    }

    public static void main(String[] args) {
        SingleObjectDeadlock shared = new SingleObjectDeadlock();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                shared.syncInstanceMethod1();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                SingleObjectDeadlock.syncStaticMethod1(shared);
            }
        });

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

        System.out.println("DEADLOCK!");
    }
}

Upon running you'll find that a deadlock occurs and the program never prints

In syncStaticMethod2()
In syncInstanceMethod2()

Upvotes: 1

Related Questions