This article belongs to the Concurrent programming network multithread study Comb series. The original text is as follows: Deadlock
A deadlock is one in which two or more threads block a lock that waits for another thread in a deadlock state to hold. Deadlocks usually occur when multiple threads are simultaneously requesting the same set of locks in a different order.
For example, if thread 1 locks A, then tries to lock B, and thread 2 already has a lock on B, and then tries to lock a, then the deadlock occurs. Thread 1 will never get B, thread 2 will never get a, and they'll never know it happened. In order to get to each other's objects (A and B), they will always block down. This situation is a deadlock.
The situation is as follows:
Thread 1 locks A, waits for B
Thread 2 locks B, waits for A
more complex deadlocks
Deadlocks can include more than 2 threads, which makes detection of deadlocks more difficult. The following are examples of 4 thread deadlocks:
Thread 1 Locks A, waits for b
thread 2 locks B, waits for C
thread 3 locks C, waits for D
thread 4 Locks D, waits 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 in Database
More complicated deadlock scenarios occur in database transactions. 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 for 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 update some of the same records at the same time, for example:
Transaction 1, request 1, Locks record 1 for update
Transaction 2, request 1, Locks record 2 for update
Transactio N 1, request 2, tries to lock record 2 for update.
Transaction 2, request 2, tries to lock record 1 for update.
It is difficult to detect and avoid deadlocks in database transactions because locks occur in different requests, and it is not possible to know all of the locks needed in advance for a transaction. Deadlock Demo:
Package thread; /** * * * * * * * @author Zhangliang * * * * * * * April 12, 2016 PM 5:51:54/public class Deadlocaktest {final static Object obj1 = new
Object ();
Final static Object Obj2 = new Object ();
public static void Main (string[] args) {//TODO auto-generated method stub deadlocaktest test = new Deadlocaktest ();
thread T1 = new Thread (test.new DeadThread1 ());
Thread t2 = new Thread (test.new DeadThread2 ());
T1.start ();
T2.start (); Class DeadThread1 implements Runnable {@Override public void run () {//TODO auto-generated method stub s
Ynchronized (obj1) {try {thread.sleep (3000);
catch (Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace ();
} System.out.println (Thread.CurrentThread (). GetName () + "Loack obj1");
Synchronized (OBJ2) {System.out.println (Thread.CurrentThread (). GetName () + "is running"); Class DeadThread2 implements Runnable {@Override PublIC void Run () {//TODO auto-generated Method stub synchronized (obj2) {try {thread.sleep (1000);
catch (Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace ();
} System.out.println (Thread.CurrentThread (). GetName () + "Loack obj2");
Synchronized (obj1) {System.out.println (Thread.CurrentThread (). GetName () + "is running"); }
}
}
}
}
Deadlock Detection:Our above program will be stuck in eclipse run, in order to simulate the online situation, deployed in the Linux environment. Run as follows:
Will be jammed, we parse to find the running program ID. Use JSATCK to view stack information:
See below for details:
Jstack-l 6081 2016-04-12 02:25:29 full thread dump Java HotSpot (TM) 64-bit Server VM (24.60-b09 mixed mode): "Attach Lis Tener "Daemon prio=10 tid=0x00007fe8a4001000 nid=0x181e waiting on condition [0x0000000000000000] Java.lang.Thread.Stat E:runnable Locked ownable synchronizers:-None "DESTROYJAVAVM" prio=10 tid=0x00007fe8c0008800, Nid=0x17c2 WA iting on condition [0x0000000000000000] Java.lang.Thread.State:RUNNABLE Locked ownable synchronizers:-No Ne "Thread-1" prio=10 tid=0x00007fe8c00a0800 nid=0x17cc waiting for monitor entry [0x00007fe8c5031000] Java.lang.Threa D.state:blocked (on object Monitor) in Deadlocaktest$deadthread2.run (deadlocaktest.java:61)-Waiting to
Lock <0x00000000af24b248> (a java.lang.Object)-locked <0x00000000af24b258> (a java.lang.Object) At Java.lang.Thread.run (thread.java:745) Locked ownable synchronizers:-None "Thread-0" prio=10 007fe8c009e800 nid=0x17cb Waiting for monitor entry [0x00007fe8c5132000] Java.lang.Thread.State:BLOCKED (on object monitor) at Deadloc
Aktest$deadthread1.run (deadlocaktest.java:38)-Waiting to lock <0x00000000af24b258> (a java.lang.Object) -Locked <0x00000000af24b248> (a java.lang.Object) at Java.lang.Thread.run (thread.java:745) locked Ownable synchronizers:-None "Service Thread" daemon prio=10 tid=0x00007fe8c008a800 nid=0x17c9 runnable [0x0000 000000000000] Java.lang.Thread.State:RUNNABLE Locked ownable synchronizers:-None "C2 CompilerThread1" D Aemon prio=10 tid=0x00007fe8c0088000 Nid=0x17c8 waiting on condition [0x0000000000000000] Java.lang.Thread.State:RUNNA BLE Locked ownable synchronizers:-None "C2 CompilerThread0" "Daemon prio=10 tid=0x00007fe8c0085800 nid=0x17c
7 Waiting on condition [0x0000000000000000] Java.lang.Thread.State:RUNNABLE Locked ownable synchronizers: -None "Signal Dispatcher "daemon prio=10 tid=0x00007fe8c0084000 nid=0x17c6 runnable [0x0000000000000000] Java.lang.Thread.State:RUNNABLE Locked ownable synchronizers:-None "Finalizer" daemon prio=10, tid=0x00007fe8c0064800 in NID=0X17C5 () [0x00007fe8c5738000] Java.lang.Thread.State:WAITING (on object monitor) at java.lang.Object.wait (Native Met HOD)-Waiting on <0x00000000af205630> (a java.lang.ref.referencequeue$lock) at Java.lang.ref.Refere
Ncequeue.remove (referencequeue.java:135)-Locked <0x00000000af205630> (a java.lang.ref.referencequeue$lock) At Java.lang.ref.ReferenceQueue.remove (referencequeue.java:151) at Java.lang.ref.finalizer$finalizerthrea D.run (finalizer.java:209) Locked ownable synchronizers:-None "Reference Handler" Daemon prio=10
fe8c0062800 nid=0x17c4 in Object.wait () [0x00007fe8c5839000] Java.lang.Thread.State:WAITING (on Object Monitor) At Java.lang.Object.waIt (Native method)-Waiting on <0x00000000af2051b8> (a java.lang.ref.reference$lock) at Java.lang.Ob Ject.wait (object.java:503) at Java.lang.ref.reference$referencehandler.run (reference.java:133)-Locked &L T;0x00000000af2051b8> (a java.lang.ref.reference$lock) Locked ownable synchronizers:-None "VM Thread" PR io=10 tid=0x00007fe8c005e000 nid=0x17c3 runnable "VM periodic Task Thread" prio=10 tid=0x00007fe8c0095800 the NID=0X17CA
Ting on condition JNI global references:106 Found one java-level deadlock: ============================= "Thread-1": Waiting to lock monitor 0x00007fe8b0004e28 (Object 0x00000000af24b248, a java.lang.Object), which was held by "Thread-0 "Thread-0": Waiting to lock monitor 0x00007fe8b00062c8 (Object 0x00000000af24b258, a java.lang.Object), which is Hel
D by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at DEadlocaktest$deadthread2.run (deadlocaktest.java:61)-Waiting to lock <0x00000000af24b248> (a Java.lang.Obje CT)-Locked <0x00000000af24b258> (a java.lang.Object) at Java.lang.Thread.run (thread.java:745) "Thr Ead-0 ": At Deadlocaktest$deadthread1.run (deadlocaktest.java:38)-Waiting to lock <0X00000000AF24B258&G T (a java.lang.Object)-locked <0x00000000af24b248> (a java.lang.Object) at Java.lang.Thread.run (thre ad.java:745) Found 1 deadlock.
You can see that a deadlock has occurred.
How to avoid deadlocks:
In some cases deadlocks can be avoided.
Lock Order
Deadlocks can occur easily when multiple threads require the same lock, but are locked in a different order.
Deadlocks do not occur if all threads are guaranteed to acquire locks in the same order. Look at the following example:
Thread 1:
lock A
lock B
thread 2: Wait for
a
lock C (then a locked)
thread 3: Wait for
a
w AIT for B, for
C
If a thread (such as thread 3) requires some lock, it must acquire the lock in the order it is determined. It only obtains the lock that is arranged in the order from the front, before it can get the lock behind it.
For example, thread 2 and thread 3 can only attempt to acquire lock C after acquiring the lock A (a) is a necessary condition for acquiring a lock C. Because thread 1 already has lock a, threads 2 and 3 need to wait until lock A is released. Then, before they try to lock a B or C, a lock must be successfully added to a.
Locking in order is an effective mechanism for deadlock prevention. However, this approach requires that you know beforehand all possible locks (translators: and do the proper sorting of these locks), but there are always times when it is unpredictable. Lock time limit
Another way to avoid deadlocks is to add a time-out when trying to acquire a lock, which means that the thread discards the lock request if it exceeds that time in the process of attempting to acquire the lock. If a thread does not successfully acquire all the required locks within a given time frame, it will roll back and release all the locks that have been acquired, then wait a random time and try again. This random wait time gives other threads the opportunity to try to get the same locks, and to keep the application running without getting a lock: After the lock timeout, you can continue to run the other things, then go back and repeat the lock logic before you do it.
Here's an example that shows two threads trying to get the same two locks in different order, and then rewind and try again after a timeout occurs:
Thread 1 locks A
thread 2 locks b
thread 1 attempts to lock B but are blocked
Thread 2 attempts to lock a but I s blocked
thread 1 ' s lock attempt on "B times out thread 1" backs up and releases A as very very
thread 1 waits Rando Mly (e.g. 257 Millis) before retrying.
Thread 2 ' s lock attempt on A times out
Thread 2 backs up and releases B as OK
Thread 2 waits randomly (e.g. m Illis) before retrying.
In the example above, thread 2 retries the lock more than thread 1 earlier than 200 milliseconds, so it can successfully obtain two locks. At this point, thread 1 attempts to acquire lock A and is in a waiting state. At the end of thread 2, thread 1 can also successfully acquire both locks (unless a thread 2 or another thread obtains some of the locks before it succeeds in getting two locks on line 1).
It is important to note that because of the timeout of the lock, we cannot assume that the scene must be deadlocked. It may also be that the thread that acquired the lock (which causes the other lines to blocks until those) takes a long time to complete its task.
In addition, if there are a lot of threads competing for the same resources at the same time, even if there is a time-out and fallback mechanism, it may cause these threads to try repeatedly but never get a lock. This behavior may not occur if there are only two threads, and the timeout for retries is set to between 0 and 500 milliseconds, but it is different if it is 10 or 20 threads. Because these threads are much more likely to wait for an equal retry time (or very close enough to cause problems).
(Translator Note: Timeout and retry mechanisms are designed to avoid competition at the same time, however, when there are many threads, the likelihood of two or more threads having the same or near timeout is very high, so even if there is a timeout after the competition, they will start to retry at the same time due to the timeout, resulting in a new round of competition, has brought new problems. )
A problem with this mechanism is that in Java, you cannot set the timeout time for the synchronized synchronization block. You need to create a custom lock, or use the tools under the Java.util.concurrent package in Java5. Writing a custom lock class is not complicated, but it is beyond the content of this article. Subsequent Java Concurrency series will cover the contents of the custom lock. ******************************************
Summary, the deadlock or the sequence is easy to go wrong, but also more difficult to debug. Try to ensure sequential access. This piece also needs to be further combined with the lock to deepen the experience.
Original address: http://ifeve.com/deadlock/
http://ifeve.com/deadlock-prevention/