- Sequential deadlock: Excessive locking, resulting in each holding a lock that the other is waiting for because of the execution order
- Resource deadlock: Multiple threads are waiting on the same resource
Deadlock due to call order
public class Test {
Object leftLock = new Object();
Object rightLock = new Object();
public static void main(String[] args) {
final Test test = new Test();
Thread a = new Thread(new Runnable() {
@Override public void run() {
int i=0;
while(i<10) { test.leftRight(); i++; }}},"aThread");
Thread b = new Thread(new Runnable() {
@Override public void run() {
int i=0;
while(i<10) { test.rightleft(); i++; }}},"bThread");
a.start();
b.start();
}
public void leftRight(){
synchronized (leftLock){
System.out.println(Thread.currentThread().getName()+":leftRight:get left");
synchronized (rightLock){
System.out.println(Thread.currentThread().getName()+":leftRight:get right");
}
}
}
public void rightleft(){
synchronized (rightLock){
System.out.println(Thread.currentThread().getName()+":rightleft: get right");
synchronized (leftLock){
System.out.println(Thread.currentThread().getName()+":rightleft: get left"); }}}}Copy the code
The output is as follows
aThread:leftRight:get left
bThread:rightleft: get right
Copy the code
Traces of deadlocks can be found through JStack
"bThread" prio=5 tid=0x00007fabb2001000 nid=0x5503 waiting for monitor entry [0x000000011d54b000]
java.lang.Thread.State: BLOCKED (on object monitor)
at main.lockTest.Test.rightleft(Test.java:52)
- waiting to lock <0x00000007aaee5748> (a java.lang.Object)
- locked <0x00000007aaee5758> (a java.lang.Object)
at main.lockTest.Test$2.run(Test.java:30)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"aThread" prio=5 tid=0x00007fabb2801000 nid=0x5303 waiting for monitor entry [0x000000011d448000]
java.lang.Thread.State: BLOCKED (on object monitor)
at main.lockTest.Test.leftRight(Test.java:43)
- waiting to lock <0x00000007aaee5758> (a java.lang.Object)
- locked <0x00000007aaee5748> (a java.lang.Object)
at main.lockTest.TestThe $1.run(Test.java:19)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
Copy the code
You can see that bThread holds the lock 0x00000007AAEE5758 and waits for 0x00000007AAEE5748, while aThread happens to hold the lock 0x00000007AAEE5748 and waits for 0x00000007AAEE5758, resulting in a deadlock
Thread starvation deadlock
public class ExecutorLock {
private static ExecutorService single=Executors.newSingleThreadExecutor();
public static class AnotherCallable implements Callable<String>{
@Override public String call() throws Exception {
System.out.println("in AnotherCallable");
return "annother success";
}
}
public static class MyCallable implements Callable<String>{
@Override public String call() throws Exception {
System.out.println("in MyCallable");
Future<String> submit = single.submit(new AnotherCallable());
return "success:"+submit.get();
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable task = new MyCallable();
Future<String> submit = single.submit(task);
System.out.println(submit.get());
System.out.println("over"); single.shutdown(); }}Copy the code
Only one line of output is executed
in MyCallable
Copy the code
Jstack observation shows the following
"main" prio=5 tid=0x00007fab3f000000 nid=0x1303 waiting on condition [0x0000000107d63000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for<0x00000007aaeed1d8> (a java.util.concurrent.FutureTask) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:425) at java.util.concurrent.FutureTask.get(FutureTask.java:187) at main.lockTest.ExecutorLock.main(ExecutorLock.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) Locked ownable synchronizers: - None .."pool-1-thread-1" prio=5 tid=0x00007fab3f835800 nid=0x5303 waiting on condition [0x00000001199ee000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007ab0f8698> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:425)
at java.util.concurrent.FutureTask.get(FutureTask.java:187)
at main.lockTest.ExecutorLock$MyCallable.call(ExecutorLock.java:26)
at main.lockTest.ExecutorLock$MyCallable.call(ExecutorLock.java:20)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- <0x00000007aaeed258> (a java.util.concurrent.ThreadPoolExecutor$Worker)
Copy the code
The main thread is waiting for a FutureTask to complete, and a thread in the thread pool is waiting for a FutureTask to complete. From the code you can see, the main thread to throw A task A thread pool, task A and dropped A task in the same thread pool B, and wait for the B, because there is only one thread in the thread pool, this will lead to B would be to stay in the blocking queue, and A still have to wait for the completion of the B, this also caused the deadlock is to wait for each other’s life
This phenomenon, in which executing task threads are blocked because they are waiting for tasks in other work queues, is called a thread starvation deadlock
Live lock
A situation where the thread is not blocked, but execution cannot continue because of some problem.
-
Message retry. When a message fails to be processed, it is retried, but for some reason, such as the message format is not correct, the parse fails, and it is retried
In this case, unfixable errors are not retried or the number of retries is limited
-
Cooperating threads respond to each other to modify their state, causing them to fail to execute. For example, two very polite people meet on the same road, give way to each other, but meet again on the same road. Each other repeatedly avoid going down
This time can choose a random retreat, so that there is a certain randomness