Reputation: 5767
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
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
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
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
Reputation: 424983
Your code will never "dead lock".
To dead lock, you must lock the other lock within a lock.
Upvotes: 1
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
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