使用jstack快速寻找死循环和死锁的原因

代码演示

  • 死循环

    • 使用步骤:
    • 1.运行服务器,使用浏览器多个窗口同时访问此路径(注意:因为多个死循环会导致电脑cpu高速运行,运行小心电脑会卡顿,测试完即可关闭)
    • 2.cmd输入jps -l命令查询服务器对应的pid
    • 3.cmd输入jstack pid > pid.txt命令,将进程运行过程存储在pid.txt中,查看此文件即可了解哪里发生了死循环
  • 死锁

    • 使用步骤:
    • 1.运行服务器,使用浏览器窗口访问此路径
    • 2.cmd输入jps -l命令查询服务器对应的pid
    • 3.cmd输入jstack pid > pid.txt命令,将进程运行过程存储在pid.txt中,查看此文件即可了解哪里发生了死锁
    • 4.查看pid.txt文件最后,发现如下内容:
    • 由此可知jstack对于发现死锁发挥着很好的效果与作用

Found one Java-level deadlock:
=============================
“Thread-4”:
waiting to lock monitor 0x000000001a5913f8 (object 0x00000000da8e4788, a java.lang.Object),
which is held by “Thread-3”
“Thread-3”:
waiting to lock monitor 0x000000001a5925d8 (object 0x00000000da8e4798, a java.lang.Object),
which is held by “Thread-4”
Java stack information for the threads listed above:
===================================================
“Thread-4”:
at com.zr.monitor_tuning.chapter2.CpuController.lambda 1 ( C p u C o n t r o l l e r . j a v a : 120 ) − w a i t i n g t o l o c k < 0 x 00000000 d a 8 e 4788 > ( a j a v a . l a n g . O b j e c t ) − l o c k e d < 0 x 00000000 d a 8 e 4798 > ( a j a v a . l a n g . O b j e c t ) a t c o m . z r . m o n i t o r t u n i n g . c h a p t e r 2. C p u C o n t r o l l e r 1(CpuController.java:120) - waiting to lock <0x00000000da8e4788> (a java.lang.Object) - locked <0x00000000da8e4798> (a java.lang.Object) at com.zr.monitor_tuning.chapter2.CpuController 1(CpuController.java:120)waitingtolock<0x00000000da8e4788>(ajava.lang.Object)locked<0x00000000da8e4798>(ajava.lang.Object)atcom.zr.monitortuning.chapter2.CpuController$Lambda$444/1678468958.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
“Thread-3”:
at com.zr.monitor_tuning.chapter2.CpuController.lambda 0 ( C p u C o n t r o l l e r . j a v a : 106 ) − w a i t i n g t o l o c k < 0 x 00000000 d a 8 e 4798 > ( a j a v a . l a n g . O b j e c t ) − l o c k e d < 0 x 00000000 d a 8 e 4788 > ( a j a v a . l a n g . O b j e c t ) a t c o m . z r . m o n i t o r t u n i n g . c h a p t e r 2. C p u C o n t r o l l e r 0(CpuController.java:106) - waiting to lock <0x00000000da8e4798> (a java.lang.Object) - locked <0x00000000da8e4788> (a java.lang.Object) at com.zr.monitor_tuning.chapter2.CpuController 0(CpuController.java:106)waitingtolock<0x00000000da8e4798>(ajava.lang.Object)locked<0x00000000da8e4788>(ajava.lang.Object)atcom.zr.monitortuning.chapter2.CpuController$Lambda$443/582497331.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.

package com.zr.monitor_tuning.chapter2;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.validator.internal.util.privilegedactions.NewInstance;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/** @version: 1.0.0
 * @Description: 使用jstack快速寻找死循环和死锁的原因
 * @author: ZR
 * @date: 2020年1月5日 下午10:01:19
 */
@RestController
@RequestMapping("/cpu")
public class CpuController {

	/**
	 * 死循环
	 * 使用步骤:
	 * 1.运行服务器,使用浏览器多个窗口同时访问此路径(注意:因为多个死循环会导致电脑cpu高速运行,运行小心电脑会卡顿,测试完即可关闭)
	 * 2.cmd输入jps -l命令查询服务器对应的pid
	 * 3.cmd输入jstack pid > pid.txt命令,将进程运行过程存储在pid.txt中,查看此文件即可了解哪里发生了死循环
	 * @return
	 */
	@RequestMapping("/loop")
	public List<Long> loop() {
		//输如错误的json数据,让getPartneridsFromJson()方法发生死循环
		String data="{\"data\":[{\"partnerid\":]";
		return getPartneridsFromJson(data);
	}
	
	/**
	 * 从json数据中获取所有的partnerid
	 * @param data
	 * @return
	 */
	public static List<Long> getPartneridsFromJson(String data){  
	    //{\"data\":[{\"partnerid\":982,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":983,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":984,\"count\":\"10000\",\"cityid\":\"11\"}]}  
	    //上面是正常的数据,不会发生死循环,但是错误的json会发生死循环
	    List<Long> list = new ArrayList<Long>(2);  
	    if(data == null || data.length() <= 0){  
	        return list;  
	    }      
	    int datapos = data.indexOf("data");  
	    if(datapos < 0){  
	        return list;  
	    }  
	    int leftBracket = data.indexOf("[",datapos);  
	    int rightBracket= data.indexOf("]",datapos);  
	    if(leftBracket < 0 || rightBracket < 0){  
	        return list;  
	    }  
	    String partners = data.substring(leftBracket+1,rightBracket);  
	    if(partners == null || partners.length() <= 0){  
	        return list;  
	    }  
	    while(partners!=null && partners.length() > 0){  
	        int idpos = partners.indexOf("partnerid");  
	        if(idpos < 0){  
	            break;  
	        }  
	        int colonpos = partners.indexOf(":",idpos);  
	        int commapos = partners.indexOf(",",idpos);  
	        if(colonpos < 0 || commapos < 0){  
	            //partners = partners.substring(idpos+"partnerid".length());//1  
	            continue;
	        }  
	        String pid = partners.substring(colonpos+1,commapos);  
	        if(pid == null || pid.length() <= 0){  
	            //partners = partners.substring(idpos+"partnerid".length());//2  
	            continue;
	        }  
	        try{  
	            list.add(Long.parseLong(pid));  
	        }catch(Exception e){  
	            //do nothing  
	        }  
	        partners = partners.substring(commapos);  
	    }  
	    return list;  
	}
	
	/**
	 * 死锁
	 * 使用步骤:
	 * 1.运行服务器,使用浏览器窗口访问此路径
	 * 2.cmd输入jps -l命令查询服务器对应的pid
	 * 3.cmd输入jstack pid > pid.txt命令,将进程运行过程存储在pid.txt中,查看此文件即可了解哪里发生了死锁
	 * 4.查看pid.txt文件最后,发现如下内容:
Found one Java-level deadlock:
=============================
"Thread-4":
  waiting to lock monitor 0x000000001a5913f8 (object 0x00000000da8e4788, a java.lang.Object),
  which is held by "Thread-3"
"Thread-3":
  waiting to lock monitor 0x000000001a5925d8 (object 0x00000000da8e4798, a java.lang.Object),
  which is held by "Thread-4"

Java stack information for the threads listed above:
===================================================
"Thread-4":
	at com.zr.monitor_tuning.chapter2.CpuController.lambda$1(CpuController.java:120)
	- waiting to lock <0x00000000da8e4788> (a java.lang.Object)
	- locked <0x00000000da8e4798> (a java.lang.Object)
	at com.zr.monitor_tuning.chapter2.CpuController$$Lambda$444/1678468958.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)
"Thread-3":
	at com.zr.monitor_tuning.chapter2.CpuController.lambda$0(CpuController.java:106)
	- waiting to lock <0x00000000da8e4798> (a java.lang.Object)
	- locked <0x00000000da8e4788> (a java.lang.Object)
	at com.zr.monitor_tuning.chapter2.CpuController$$Lambda$443/582497331.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

	 * 由此可知jstack对于发现死锁发挥着很好的效果与作用
	 * @return
	 */
	@RequestMapping("/deadLock")
	public String deadLock() {
		Object object1=new Object();
		Object object2=new Object();
		new Thread(()->{
			synchronized (object1) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized (object2) {
					System.out.println("object1 finish");
				}
			}
		}).start();
		
		new Thread(()->{
			synchronized (object2) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized (object1) {
					System.out.println("object2 finish");
				}
			}
		}).start();
		return "deadLock";
	}
	
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值