• 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.

  1. 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

  2. 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