Reputation: 1033
here is the code
public class TestDeadlockExample1 {
public static void main(String[] args) {
final String resource1 = "xyz";
final String resource2 = "pqr";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");
try { Thread.sleep(10000);} catch (Exception e) {}
synchronized (resource2) {
System.out.println("Thread 1: locked resource 2");
}
}
}
};
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
try { Thread.sleep(10000);} catch (Exception e) {}
synchronized (resource1) {
System.out.println("Thread 2: locked resource 1");
}
}
}
};
t1.start();
t2.start();
System.out.println("completed");
}
}
here
t1.start();
t2.start();
System.out.println("completed");
here
in this t1.start() and t2.start() are written in sequential order, so my doubt is that both the thread starts at the same or not or t1 starts, executes then comes to t2 and executes, if this is correct, how this becomes a deadlock situation..i want to know the execution of these threads
Upvotes: 1
Views: 301
Reputation: 384
The order of thread execution is not defined.
There is a high risk for your program to go to deadlock. But you can slightly change the order of lock in the second thread to avoid deadlock. I've modified and given below. Again this depends on the logic you are going to write.
Thread t2 = new Thread() {
public void run() {
synchronized (resource1) {
System.out.println("Thread 2: locked resource 2");
try { Thread.sleep(10000);} catch (Exception e) {}
System.out.println("Thread 2: Waiting for resource 1...");
synchronized (resource2) {
System.out.println("Thread 2: locked resource 1 and 2");
}
}
}
};
Upvotes: 0
Reputation: 1519
"so my doubt is that both the thread starts at the same or not or t1 starts, executes then comes to t2 and executes"
Simply because the threads t1 and t2 are spawned sequentially, does not imply that they execute sequentially. Threads are used for parallel execution of units of work.
Due to the sleep method calls in your code, it will deadlock because
t1 acquires R1 or t2 acquires t2. The order is indeterminate
Both threads sleep for 10 seconds after acquiring their respective resource, so we can be say with high degree of certainty in this example that both threads have acquired the resources at some point during the sleep period of the other.
When t1 or t2 wake up and try to acquire the second resource, which is already held by the respective threads sibling it will block. Both threads will block attempting to acquire the resource held by the other.
This scenario only occurs because the threads are executing in parallel, not sequentially.
Please see http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Upvotes: 0
Reputation: 12316
When you launch your java program, JRE spawns main thread and that main thread executes your main
method.
When you call t1.start()
, new thread spawns and executes first anonymous class's run
method. From this point there are 2 threads executing simultaneously in your program: "main thread" and "thread 1".
When you call t2.start()
, another thread spawns and executes second anonymous class's run
method. From this point there are 3 threads executing simultaneously in your program: "main thread", "thread 1", "thread 2".
The order in which threads are executing is not defined. It could be anything. Generally they are executing simultaneously.
Your "thread 1" and "thread 2" acquire locks on resource1
and resource2
correspondingly and sleep for 10 seconds. While that happens, your "main" thread finishes its execution. But there are 2 more threads in your program, so while main
method finished, program is not finished yet.
After sleeping your "thread 1" and "thread 2" trying to acquire locks on resource 2
and resource 1
, but those locks are already acquired so they will wait until lock holder will release it. Lock holder will never release it, as it waits for other resource so this program will never stop. That's classic deadlock situation.
Upvotes: 1
Reputation: 135992
sleep() guarantees that both t1 and t2 acquire their first lock before they proceed to their second lock. No matter which thread runs first.
Upvotes: 0
Reputation: 36304
in this t1.start() and t2.start() are written in sequential order, so my doubt is that both the thread starts at the same or not or t1 starts, executes then comes to t2 and executes
A call to start()
doesn't ensure that a Thread starts immediately. A native call is made via start0()
which inturn calls the OS to fork a thread. So, basically, thread2 can start before thread1. You have no control over which thread starts first.
how this becomes a deadlock situation
There is a probability of deadlock here because t1
might get lock on resource1
and t2
might get lock on resource2
at the same time. Now, both threads want the resource held by the other thread. Hence you have a deadlock.
So as a standard practice, both t1
and t2
should acquire lock in the same sequence.
Upvotes: 0
Reputation: 81539
I have learned that to prevent deadlocks, you need to make the synchronized
block be consistently the same.
public void run() {
synchronized (resource1) {
synchronized (resource2) {
System.out.println("Thread 1: locked resource 1");
System.out.println("Thread 1: locked resource 2");
try { Thread.sleep(10000);} catch (Exception e) {}
}
}
}
and
Thread t2 = new Thread() {
public void run() {
synchronized (resource1) {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
System.out.println("Thread 2: locked resource 1");
try { Thread.sleep(10000);} catch (Exception e) {}
}
}
}
};
Upvotes: 0