Deadlock should be said to be a common scenario in concurrent programming, it can be said that if the program produced a deadlock that will have a fatal effect on the program, so troubleshooting location, repair deadlock is critical;
We all know that deadlocks are caused by multiple objects or multiple threads that require each other to lock on each other and do not release the lock held by each other, causing both sides to be permanently blocked;
As shown, thread 1 holds the lock of object 1, Thread 2 holds the lock of Object 2, holds this thread 1 and wants to get object 2 object lock, thread 2 want to get Object 1 object lock, at this time because both sides did not get to the desired lock, the task did not complete so also did not release the lock, resulting in a deadlock, so blocking, production
Deadlock detection
The need to detect deadlocks must first have a deadlock, the following demo simulation of a deadlock generation;
Publicclassdeadlockdemoextendsthread{privatebaseobj first;privatebaseobj Second;publicdeadlockdemo (String name, Baseobj First, baseobj second) {super (name); This.first = First;this.second = Second;} Publicvoidreentrantlock () throwsinterruptedexception{ First.lock (); SYSTEM.OUT.PRINTLN ( String.Format ("%s hold:%s object lock, waiting to get:%s object Lock", This.getname (), first, second)); Second.lock (); First.unlock (); Second.unlock ();} @Overridepublicvoidrun () {try{ Reentrantlock (); }catch (Exception e) { E.printstacktrace (); }}publicstaticvoidmain (string[] args) throwsinterruptedexception{ Objone One =newobjone (); Objtwo-=newobjtwo (); Deadlockdemo thread1 =newdeadlockdemo ("Thread1", one, and both); Deadlockdemo thread2 =newdeadlockdemo (" Thread2 ", one, one); Thread1.start (); Thread2.start (); thRead1.join (); Thread2.join ();} }
Running the demo above will see that the program is blocked, unable to end the operation, only see the following results:
Thread1 hold: Objone object lock, waiting to get: Objtwo object lock Thread2 hold: Objtwo object lock, waiting to get: Objone object lock
This demo can not end the operation is due to the creation of a deadlock, two threads are dealing with each other to obtain the object lock held by each other;
This time to solve the problem you need to find out where the deadlock, through the code is usually not easy to find the deadlock, of course, our program is easy to find, because we deliberately produced a deadlock, so we need tools to detect deadlocks, the tools available here are: Jconsole, JVISUALVM, Jstack and so on, these tools are actually the JDK comes with, the usage is very similar;
The JVISUALVM is used here to detect if the current demo program has a deadlock, open the JVISUALVM connection to the current application to see the program's monitoring information, such as memory, CPU, performance, GC, and so on, open the tab item of the thread to view the thread information Here it is obvious to see the hint that the program was detected in addition to the deadlock!
Click on thread dump to see the stack information of the thread, from which you can see the details of the thread and locate the deadlock;
You can see the cause of the deadlock in the thread, Thrad2 is waiting for Thread1, Thread1 is waiting for Thread1, from the stack information can locate the location of the deadlock;
Deadlock Scan
In addition to the discovery of problems in the program after we go to scan the deadlock, we can also be in real-time scanning program to find out if there is a deadlock in the program;
The JDK provides a Mxbean API that can be used to scan for deadlocks, Threadmxbean provides a finddeadlockedthreads () method that can be used to find the thread that generated the deadlock, and here in the demo program above, add a method to scan the deadlock, Although this method can be scanned to deadlock but because each time the thread to the snapshot of the program performance will have a relatively large impact, so use caution;
Publicstaticvoidscandeadlock () {Threadmxbean MxBean = Managementfactory.getthreadmxbean (); Runnable Runnable = () {long[] ids = Mxbean.finddeadlockedthreads (); SYSTEM.OUT.PRINTLN ("Scan deadlock ..."), if (IDs!=null) {threadinfo[] Threadinfos = mxbean.getthreadinfo (IDs); for (Threadi NFO Threadinfo:threadinfos) {System.out.println (threadinfo); } } }; Scheduledexecutorservice Executorservice =newscheduledthreadpoolexecutor (5, Executors.defaultthreadfactory ()); Executorservice.scheduleatfixedrate (runnable,1,5, timeunit.seconds);}
Avoid deadlocks
The best way to solve the deadlock is to avoid deadlocks, such as the above demo we can use the lock () method without parameters to use the Trylock method, Trylock can also specify the acquisition lock time-out time, until the timeout has not been acquired to the lock will discard the acquisition lock, Of course there are other ways to avoid deadlocks;
1, avoid the use of multiple locks, long-time holding locks;
2, design a number of locks to obtain the order
3. Using the acquire lock method with timeout
Locating and repairing of deadlock in Java