I am reading the book Java Concurrency in Practice, and here is what it says about deadlock.
JVM does not recover from deadlock, and only way to get rid of dead lock is to restart the server. It also mentions that JVM uses graph search where Thread acts as graph node and edge between two threads A and B is defined as Thread A is waiting for lock on resource already held by thread B. This graph is directed and if there is any cycle in this graph, then there is deadlock
Now my question is that if JVM knows that there is deadlock, then why does not it kill one thread and let other proceed? is there any specific reason behind this or my question itself is based on wrong conclusion?
Please let me know your views about this. Thanks in advance!!!
-
3As I always mention, Comments are more useful than downvoting. so please put your comments rather than simply downvoting.AKS– AKS2013年09月20日 02:44:02 +00:00Commented Sep 20, 2013 at 2:44
-
1I think that this question doesn't deserve downvote. +1 for counter balancing downvote. Now , a quick question for you : How JVM will come to know that Which thread do you want to kill in case of deadlock?Mac– Mac2013年09月20日 02:47:20 +00:00Commented Sep 20, 2013 at 2:47
-
@Mac, I am assuming if JVM kills any one of the threads, then deadlock will be resolved, but Yes, I agree, it will be unfair to the thread which will get killed, but at least no restart will be required. And my question is inspired from database transaction deadlocks, where one of the transactions are killed in case of deadlock.AKS– AKS2013年09月20日 02:49:51 +00:00Commented Sep 20, 2013 at 2:49
-
2By not killing on of the threads in deadlock situation, JVM ensures the safety of your code by avoiding unpredictable and inconsistent changes in state variables, or any inconsistent transaction and many other shared among the threads.Mac– Mac2013年09月20日 02:54:10 +00:00Commented Sep 20, 2013 at 2:54
-
@Mac, Now I am getting the reason, and I agree that data inconsistency is the main reason that JVM does not interferes in this situation.AKS– AKS2013年09月20日 02:58:55 +00:00Commented Sep 20, 2013 at 2:58
2 Answers 2
Now my question is that if JVM knows that there is deadlock, then why does not it kill one thread and let other proceed? is there any specific reason behind this or my question itself is based on wrong conclusion?
How could the JVM make the decision about which thread to kill? What if the JVM, in releasing the lock by force, allowed invalid data to enter some sort of critical database?
The JVM cannot make these sort of decisions arbitrarily. It reports on the deadlock but cannot automagically recover from it.
You could see this problem in any situation where two critical objects are being modified with locks but two threads are locking them in a different order. Database transactions are able to recover from such deadlocks because they are designed to roll back tables and indices but Java synchronized locks don't have implicit memory rollback capabilities. By killing one thread and releasing its locks, the JVM would be allowing partial memory updates to be propagated.
4 Comments
Killing one thread would not allow the other to proceed sanely. In fact, killing the thread would be fatal. The reason a thread acquires a lock in the first place is to keep other threads out of some data structure while that data structure is an inconsistent state. Releasing the lock with the data structure still in an inconsistent state would fatally contaminate the process context.
For example:
Thread A locks object 1.
Thread B locks object 2.
Thread A puts object 1 in an inconsistent state.
Thread B puts object 2 in an inconsistent state.
Thread A blocks on object 2.
Thread B blocks on object 1.
How can either thread proceed now? Each is waiting for the other thread to return an object into a consistent state.
Here's a clearer example in case you don't understand what I mean by an inconsistent state. Consider this code:
- Acquire the lock that protects
fooandbar. - Start World War III if
fooplusbaris not 10. (No worries, the programmer carefully made surefooplusbaris always 10 unless he actually has to start World War III.) - Increment
foo. - Acquire some other lock.
- Decrement
bar - Release the other lock.
- Release the lock that protects
fooandbar.
What do you do if you deadlock at step 4? You cannot release the lock that protects foo and bar as the next thread to run this code would start World War III. Clearly, detailed understanding of what this specific code does is needed to untangle the deadlock.