定位:
- 用top定位哪个进程对cpu的占用过高
- ps H -eo pid,tid,%cpu | grep进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)
- jstack进程id
- 可以根据线程id找到有问题的线程,进一步定位到问题代码的源码行号
首先用nohup java Demo1_16 &命令执行准备好的Demo程序
然后使用top命令查看信息,可以看到最上面的java程序对cpu的占用达到了92%
下一步使用ps H -eo pid,tid,%cpu | grep进程id 查看进程的情况(pid是进程id,tid是线程id),可以看到有一个进程id为2911683的cpu占用率达到了%92
使用jstack命令查看
注意:上面使用ps命令查看的信息中的进程id是十进制的,但是使用jstack命令查看的信息中进程id是十六进制的,因此需要换算一下
根据id可以找到在11行的代码中可能有问题
回头看刚才运行的代码可以看到在第11行的地方有一个while(true)循环一直在占用cpu
例子二:程序运行很长时间没有结果运行一段准备好的代码
可以看到发生了死锁,线程1和线程2在互相等待对方的锁
代码例子一的代码
public class Demo1_16 {
public static void main(String[] args) {
new Thread(null, () -> {
System.out.println("1...");
while(true) {
}
}, "thread1").start();
new Thread(null, () -> {
System.out.println("2...");
try {
Thread.sleep(1000000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "thread2").start();
new Thread(null, () -> {
System.out.println("3...");
try {
Thread.sleep(1000000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "thread3").start();
}
}
例子二的代码
class A{};
class B{};
public class Demo1_3 {
static A a = new A();
static B b = new B();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
synchronized (a) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println("我获得了 a 和 b");
}
}
}).start();
Thread.sleep(1000);
new Thread(()->{
synchronized (b) {
synchronized (a) {
System.out.println("我获得了 a 和 b");
}
}
}).start();
}
}



