死锁:两个或两个以上的线程在执行的过程中,因为竞争资源或者彼此期待彼此而造成彼此期待彼此,线程不再往下执行。

依据以上示例图构建连个死锁程序
(1)DeadLock

package com.high.concurrency.currency02.eat;public class DeadLock extends Thread {    private String first;    private String second;    public DeadLock(String name, String first, String second) {        super(name);        this.first = first;        this.second = second;    }    @Override    public  void run() {        synchronized (first) {            try {                System.out.println(this.getName() + " ...synchronized:===> 【first】" + first);                Thread.sleep(1000L);                synchronized (second) {                    System.out.println(this.getName() + " ...synchronized:===>【second】 " + second);                }            } catch (InterruptedException e) {}        }    }    public static void main(String[] args) throws InterruptedException {        String lockA = "lockA";        String lockB = "lockB";        DeadLock t1 = new DeadLock("t1", lockA, lockB);        DeadLock t2 = new DeadLock("t2", lockB, lockA);        t1.start();        t2.start();        t1.join();        t2.join();    }}
(2)PhilosopherEatingpackage com.high.concurrency.currency02.eat;public class PhilosopherEating extends Thread {    protected Object tool;    static Object fork1 = new Object();    static Object fork2 = new Object();    public PhilosopherEating(Object obj) {        this.tool = obj;        if(tool == fork1) {            this.setName("哲学家A");        }        if (tool == fork2) {            this.setName("哲学家B");        }    }    @Override    public void run() {        if(tool == fork1) {            synchronized (fork1) {                try {                    Thread.sleep(500);                } catch (Exception e) {                    e.printStackTrace();                }                synchronized (fork2) {                    System.out.println("哲学家A开始吃饭了");                }            }        }        if (tool == fork2) {            synchronized (fork2) {                try {                    Thread.sleep(500);                } catch (InterruptedException e) {                    e.printStackTrace();                }                synchronized (fork1) {                    System.out.println("哲学家B开始吃饭了");                }            }        }    }    public static void main(String[] args) throws InterruptedException {        PhilosopherEating philosonpherA = new PhilosopherEating(fork1);        PhilosopherEating philosonpherB = new PhilosopherEating(fork2);        philosonpherA.start();        philosonpherB.start();        Thread.sleep(1000);    }}

上述程序都体现一个特点: 存在两个线程,呈现我应用这以后的资源, 申请对方正在应用的资源,而对方尚未开释该资源导致线程阻塞。
查找线程死锁的方法:jps + jstack
首先在终端输出jps,查找到对应的死锁过程号:

获取到对应的死锁过程,输出jstack + 过程号, 找到对应的报错信息,依据报错信息进行下一步的批改