A deadlock is a situation in which two or more threads are permanently blocked, and this generation is accompanied by at least two threads and two or more resources.
Deadlock Example:
Public classThreaddeadlock { Public Static voidMain (string[] args)throwsinterruptedexception {Object obj1=NewObject (); Object Obj2=NewObject (); Object obj3=NewObject (); Thread T1=NewThread (NewSyncthread (Obj1, Obj2), "T1"); Thread T2=NewThread (NewSyncthread (Obj2, obj3), "T2"); Thread T3=NewThread (NewSyncthread (Obj3, obj1), "T3"); T1.start (); Thread.Sleep (5000); T2.start (); Thread.Sleep (5000); T3.start (); } } classSyncthreadImplementsrunnable{PrivateObject obj1; PrivateObject Obj2; PublicSyncthread (Object O1, Object O2) { This. obj1=O1; This. obj2=O2; } @Override Public voidrun () {String name=Thread.CurrentThread (). GetName (); SYSTEM.OUT.PRINTLN (Name+ "acquiring lock on" +obj1); synchronized(obj1) {System.out.println (name+ "acquired lock on" +obj1); Work (); SYSTEM.OUT.PRINTLN (Name+ "acquiring lock on" +obj2); synchronized(obj2) {System.out.println (name+ "acquired lock on" +obj2); Work (); } System.out.println (Name+ "released lock on" +obj2); } System.out.println (Name+ "released lock on" +obj1); SYSTEM.OUT.PRINTLN (Name+ "finished execution."); } Private voidWork () {Try{Thread.Sleep (30000); } Catch(interruptedexception e) {e.printstacktrace (); } }}
Avoid deadlocks
There are many guidelines that we can use to avoid deadlocks.
- Avoid nesting blocking: This is the main reason for deadlocks, and if you already have a resource you should avoid blocking another resource. If you run with only one object blocked, it is almost impossible to have a deadlock situation. For example, here is another run () method that does not have a nested block in operation, and the program runs without deadlock and runs successfully.
- block only requests: you should just want the resources you want to run to get blocked, such as the full object resources I'm blocking in the above program. But if we are only interested in one of the fields in which it belongs, then we should block that particular field rather than the complete object.
- avoid waiting indefinitely: If two threads are waiting for the end of the object, an indefinite use of the thread joins, if your thread must wait for the end of another thread, if waiting for the end of the process to join is best prepared for the longest time.
Use the class within the Java.util.concurrent package to set the timeout.
Importjava.util.concurrent.Callable;Importjava.util.concurrent.ExecutionException;ImportJava.util.concurrent.ExecutorService;Importjava.util.concurrent.Executors;ImportJava.util.concurrent.FutureTask;ImportJava.util.concurrent.TimeUnit;Importjava.util.concurrent.TimeoutException; Public STRICTFP classmain{ Public Static voidMain (string[] args)throwsinterruptedexception{ executorservice executor= executors. Newsinglethreadexecutor (); Futuretask <String> Futuretask =NewFuturetask<string> (New callable<String>() { PublicString Call () {//The real task is executed here, where the return value type is string and can be any type Try{Thread.Sleep (2000); } Catch(interruptedexception e) {//TODO auto-generated Catch blockSystem.out.println ("interruptered"); } return"Haha"; } }); Executor.execute (Futuretask); //There's something else you can do here.String result=NULL; Try{result= Futuretask.get (Timeunit.milliseconds);//The result is obtained, and the timeout execution time is set at 5 seconds. You can also use Future.get (), do not set the execution timeout time to get results}Catch(interruptedexception e) {futuretask.cancel (true); } Catch(executionexception e) {futuretask.cancel (true); } Catch(TimeoutException e) {futuretask.cancel (true); } finally{executor.shutdown (); } System.out.println (Result); }}
Java Multithreading (1) Implementation of multi-threaded deadlock and synchronization timeout