Java模拟排查线程死锁问题

一、模拟死锁

public class App 
{
    public static void main( String[] args )
    {
        Object object1 = new Object();
        Object object2 = new Object();

        System.out.println("main thread start");
        Thread thread1 = new Thread(new Task1(object1,object2));
        thread1.start();


        Thread thread2 = new Thread(new Task2(object1,object2));
        thread2.start();

        System.out.println("main thread end");

    }

}

class Task1 implements Runnable {

    private Object curObj1;
    private Object curObj2;

    public Task1 (Object obj1,Object obj2) {
        this.curObj1 = obj1;
        this.curObj2 = obj2;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName() + " start");

        synchronized (curObj1) {
            System.out.println(Thread.currentThread().getName() + " get lock on Object1");

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (curObj2) {
                System.out.println(Thread.currentThread().getName() + " get lock on Object2");
            }

        }

        System.out.println(Thread.currentThread().getName() + " end");
    }
}

class Task2 implements Runnable {

    private Object curObj1;
    private Object curObj2;

    public Task2 (Object obj1,Object obj2) {
        this.curObj1 = obj1;
        this.curObj2 = obj2;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName() + " start");

        synchronized (curObj2) {
            System.out.println(Thread.currentThread().getName() + " get lock on Object2");

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (curObj1) {
                System.out.println(Thread.currentThread().getName() + " get lock on Object1");
            }
        }



        System.out.println(Thread.currentThread().getName() + " end");
    }
}

1、两个线程分别互相等待对方释放对象锁

2、打包成jar(注意在POM中加入maven-jar-plugin插件,否则打包出来的jar在执行时会报错找不到manifest)

3、java  -jar   jarname  执行

二、排查死锁

1、top查看CPU和内存使用率

2、找到资源占用率比较高的进程PID

3、分析PID

4、显示PID下面的线程

     top -H  -p  pid

5、查看具体某个线程

     jstack -l  pid | grep  xxx -A  20

6、jvm常用命令

(1)jps 查看启动的JVM进程

(2)jinfo  pid 查看某个JVM进程ClassPath、VM参数设置等

(3)jstat 查看某个JVM进程运行状态:GC情况等

(4)jstack 查看某个JVM进程下所有线程的运行状态

(5)jmap 查看某个JVM进程下堆中存储的对象


查看结果:

Java模拟排查线程死锁问题_第1张图片



你可能感兴趣的:(Java多线程)