1. 解决方式
- ps aux | grep java 查看到当前java进程使用cpu、内存、磁盘的情况获取使用量异常的进程
- top -Hp 进程pid检查当前使用异常线程的pid
- 把线程pid变为16进制如31695-》7bcf然后得到0x7bcf
printf %x 36044
- jstack 进程的pid | grep A20Ox7bcf 得到相关进程的代码
jstack 36032 > 1.txt
2. 可能导致CPU占用率过高的场景
- 无限while循环
- 频繁GC:降低GC频率
- 频繁创建新对象:合理使用单例
- 序列化和反序列化:选择合理的API实现功能
- 正则表达式:减少字符匹配期间执行的回溯
- 频繁的线程上下文切换
3. 案例
public class JstackDeadLockDemo {
/**
* 必须有两个可以被加锁的对象才能产生死锁,只有一个不会产生死锁问题
*/
private final Object obj1 = new Object();
private final Object obj2 = new Object();
public static void main(String[] args) {
new JstackDeadLockDemo().testDeadlock();
}
private void testDeadlock() {
Thread t1 = new Thread(() -> calLock_Obj1_First());
Thread t2 = new Thread(() -> calLock_Obj2_First());
t1.start();
t2.start();
}
/**
* 先synchronized obj1,再synchronized obj2
*/
private void calLock_Obj1_First() {
synchronized (obj1) {
sleep();
System.out.println("已经拿到obj1的对象锁,接下来等待obj2的对象锁");
synchronized (obj2) {
sleep();
}
}
}
/**
* 先synchronized obj2,再synchronized obj1
*/
private void calLock_Obj2_First() {
synchronized (obj2) {
sleep();
System.out.println("已经拿到obj2的对象锁,接下来等待obj1的对象锁");
synchronized (obj1) {
sleep();
}
}
}
/**
* 为了便于让两个线程分别锁住其中一个对象,
* 一个线程锁住obj1,然后一直等待obj2,
* 另一个线程锁住obj2,然后一直等待obj1,
* 然后就是一直等待,死锁产生
*/
private void sleep() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}