The following is transferred from http://ifeve.com/deadlock/:
A deadlock is two or more threads that block locks that are held by threads waiting for other deadlock states. Deadlocks typically occur when multiple threads are simultaneously requesting the same set of locks in a different order.
For example, if thread 1 locks A and then tries to lock B, and thread 2 has locked B, and then tries to lock a, a deadlock occurs. Thread 1 will never get B, thread 2 will never get a, and they will never know what happened. In order to get each other's objects (A and B), they will be blocked forever. This situation is a deadlock.
The situation is as follows:
Thread 1 for 2 for A
Here is an example of a TreeNode class that invokes a different instance of the Synchronized method:
Public classTreeNode {TreeNode parent=NULL; List Children=NewArrayList (); Public synchronized voidAddChild (TreeNode child) {if(! This. Children.contains (Child)) { This. Children.add (child); Child.setparentonly ( This); } } Public synchronized voidaddchildonly (TreeNode child) {if(! This. Children.contains (child) { This. Children.add (child); } } Public synchronized voidsetParent (TreeNode parent) { This. Parent =parent; Parent.addchildonly ( This); } Public synchronized voidsetparentonly (TreeNode parent) { This. Parent =parent; }}
If thread 1 calls the Parent.addchild (child) method While there is another thread 2 calling the Child.setparent (parent) method, the parent in two threads represents the same object, and child is the same, and a deadlock occurs at this point. The following pseudo-code illustrates this process:
// Locks Parent -//locksChild -to-parent.addchildonly ()
First thread 1 calls Parent.addchild (child). Because Addchild () is synchronous, thread 1 locks the parent object to keep it from being accessed by other threads.
Then thread 2 calls Child.setparent (parent). Because SetParent () is synchronous, thread 2 locks the child object so that no other thread can access the object.
Now the child and the parent object are locked by two different threads. The next thread 1 attempts to call the Child.setparentonly () method, but because the child object is now locked by thread 2, the call is blocked. Thread 2 also tries to call Parent.addchildonly (), but because the parent object is now locked by thread 1, thread 2 is also blocked at that method. Now two threads are blocked and waiting for a lock held by another thread.
Note: As described above, these two threads need to call both the Parent.addchild (child) and the Child.setparent (parent) methods, and are the same parent object and the same child object before deadlocks can occur. The above code may run for a period of time before a deadlock occurs.
These threads need to acquire locks at the same time. For example, if thread 1 is slightly ahead of thread 2 and then successfully locks A and B two objects, thread 2 will be blocked when attempting to lock B, so that the deadlock does not occur. Because thread scheduling is often unpredictable, there is no way to predict exactly when a deadlock will occur, and it can only happen.
More complex deadlocks
Deadlocks can be more difficult to detect because they may contain more than 2 threads. The following is an example of a deadlock that occurs with 4 threads:
Thread 1 for 2 for 3 for 4 for A
Thread 1 waits for thread 2, thread 2 waits for thread 3, thread 3 waits for thread 4, thread 4 waits for thread 1.
Deadlock of the database
A more complex deadlock scenario occurs in a database transaction. A database transaction may consist of multiple SQL update requests. When a record is updated in a transaction, the record is locked to avoid update requests from other transactions until the first transaction ends. Each update request in the same transaction may lock some records.
Deadlocks are most likely to occur when multiple transactions need to be updated on some of the same records, for example:
For forfor update .
Because locks occur in different requests, and it is impossible for a transaction to know in advance all the locks it requires, it is difficult to detect and avoid deadlocks in database transactions.
16. Java concurrency and multi-threaded-deadlock