一、模拟死锁
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进程下堆中存储的对象
查看结果: