pvllnspk
pvllnspk

Reputation: 5767

can not reproduce deadlock using the next code

can not reproduce deadlock using the next code

I am trying yo get a deadlock using the next code, but it seems that it works good.

Please see below:

public class Deadlock {

    static Object lock1 = new Object();
    static Object lock2 = new Object();

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (lock1) {
                        System.out.println("Thread 1: locked lock1");
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2) {
                        System.out.println("Thread 1: locked lock2");
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (lock2) {
                        System.out.println("Thread 2: locked lock2");
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock1) {
                        System.out.println("Thread 2: locked lock1");
                    }
                }
            }
        }).start();

    }

}

What I don't understand in this case or what's wrong in this code?

Upvotes: 0

Views: 300

Answers (6)

Andrew Clark
Andrew Clark

Reputation: 208405

If you are trying to get a deadlock, you need to nest the synchronized blocks so that you attempt to whole both locks simultaneously:

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (lock1) {
                        System.out.println("Thread 1: locked lock1");
                        try {
                            // Sleep to allow Thread2 to obtain lock2
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized (lock2) {
                            System.out.println("Thread 1: locked lock2");
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        // Sleep to allow Thread1 to obtain lock1
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2) {
                        System.out.println("Thread 2: locked lock2");
                        synchronized (lock1) {
                            System.out.println("Thread 2: locked lock1");
                        }
                    }
                }
            }
        }).start();

Note that the locks are acquired in reverse order, with sleeps to ensure the following acquisition order:

Thread 1 acquires lock1
Thread 2 acquires lock2
Thread 1 attempts to acquire lock2       <--- DEADLOCK
Thread 2 attempts to acquire lock1       <--- DEADLOCK

Note that the last two can happen in either order, but the deadlock will occur regardless.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691635

Why would the above code cause a deadlock? Each thread only locks one lock at a time, so if the other thread tries to lock it, it just has to wait for the first one to release it.

You would have a serious risk of deadlock if the threads did

synchronized (lock1) {
    synchronized (lock2) {
        ...
    }
}

and

synchronized (lock2) {
    synchronized (lock1) {
        ...
    }
}

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533462

To get a deadlock you need to hold two locks at once. You can hold the first lock for the whole loop.

Upvotes: 1

Bohemian
Bohemian

Reputation: 424983

Your code will never "dead lock".

To dead lock, you must lock the other lock within a lock.

Upvotes: 1

sjlee
sjlee

Reputation: 7866

To cause a deadlock, you need to hold both locks in these threads in reverse order.

// thread 1
public void run() {
    synchronized (lock1) {
        synchronized (lock2) {
            // do something
        }
    }
}

// thread 2
public void run() {
    synchronized (lock2) {
        synchronized (lock1) {
            // do something
        }
    }
}

This is necessary, but not sufficient. To be able to simulate the deadlock, you need to make sure both threads acquire their first locks respectively successfully before attempting to acquire the next.

Upvotes: 3

Jato
Jato

Reputation: 138

Have the second thread try to get a lock on lock1. That's the classic way to invoke deadlock. Two resources locked in different orders.

Sorry... didn't scroll down far enough in your code... feeling foolish

Upvotes: 0

Related Questions