使用visual vm 分析线程(上)

  • 博客分类:
  • 线程安全
多线程并发synchronizedvisual vm线程安全 

网上很多visual vm的指南手册之类,visual vm最新的下载好后,直接运行即可。

如果无法运行,在右键选择要执行的类,选择Run As-->Open Run Dialog,在新窗口中选择Arguments标签。

vm参数上增加:-XX:+PerfBypassFileSystemCheck

【代码背景介绍——4个线程】

客户端向我的Server中发送消息,我的代码中有一个正常消息List infoList,一个异常的消息List errList。对于这两个List,都各自有一个监听线程,监听到了List中有数据,则发送出去,无数据则休眠。

同时为了防止数据丢失,每个数据在进入这两个List前都要写入文件系统。当数据发送成功后,则将正常发送数据写入待删除的infoDelList,异常重发的数据写入errDelList。因此又增加了infoDelList和errDelList监听,当这两个List有数据,则遍历这并删除文件系统的数据。

因此我有4个线程监听这4个List。

【开始测试】

第一次测试。

先启动服务器,1分钟内无客户端发送的数据,那么此时4个监听线程都在休眠。

1分钟后,客户端开始每一秒钟并发20个,总共5000个数据。

这次我让所有的客户端数据全部可以发送成功。那么通过visual vm可以看到2个监听应该一直在休眠的。如图:

解释:

【0:00-1:00】:可以看到有4个线程在有并发数据前都在紫色的休眠状态。

【1:00-2:00】:当并发开始后,Thread-0和Thread-2一直在Sleeping上的紫色状态有些开始有绿色的Running的时间片了。在1分18秒时刻,Thread-2线程正在执行,Thread-0线程在该时刻是红色的监视状态。表示Thread-2想执行synchronized中的代码,但是没有锁,进入堵塞等待了,可以看到在1分35秒左右Thread-2获得时间片执行了。

说了半天的Thread-1,Thread-2,怎么知道他们对应的代码是哪个呢?visual vm中显示的名字其实就是线程的名字。可以通过打印日志,查看代码中个线程和visual vm的线程名字对应。如下在run方法中,进入循环之前打印前获取线程名字:Thread.currentThread().getName(),下面这个线程打印出来是Thread-0 。

Java代码  
  1. import java.io.File;
  2. import java.util.List;
  3. import org.apache.log4j.Logger;
  4. /**
  5. * 消息中心磁盘文件删除监听
  6. * @author zhuoyueping
  7. *
  8. */
  9. public class DiskDeleteListener extends Thread{
  10. public static  List pathList =  null;
  11. private static final Logger log = Logger.getLogger(DiskDeleteListener.class);
  12. private static DiskDeleteListener instance = new DiskDeleteListener();
  13. private DiskDeleteListener(){
  14. super();
  15. }
  16. public static DiskDeleteListener getInstance(){
  17. return instance;
  18. }
  19. public void run() {
  20. log.info("Thread Name="+Thread.currentThread().getName());
  21. while(true){{
  22. try {
  23. if(DiskDeleteListener.pathList!=null&&DiskDeleteListener.pathList.size()>0){
  24. for(int i = 0;i<DiskDeleteListener.pathList.size();){
  25. String path = (String) DiskDeleteListener.pathList.get(i);
  26. if(path!=null){
  27. File file = new File(path);
  28. if(file.exists()){
  29. //删除文件
  30. file.delete();
  31. DiskDeleteListener.pathList.remove(i);
  32. }else{
  33. DiskDeleteListener.pathList.remove(i);
  34. log.error("第"+i+"个,"+"文件不存在,清理内存数据完成"+path);
  35. }
  36. }else{
  37. DiskDeleteListener.pathList.remove(i);
  38. }
  39. }
  40. }
  41. Thread.sleep(1000);
  42. } catch (InterruptedException e) {
  43. e.printStackTrace();
  44. log.error(e);
  45. }
  46. }
  47. }
  48. }
  49. }

如果覆盖start方法,在start方法中去取Thread.currentThread().getName(),将得到main,即启动该线程的线程名。因此Thread.currentThread()一定是在run中的线程,一个线程的start被执行时候,Thread.currentThread()获得的是它的父线程。

Thread-0,用于删除已经发送成功的消息的磁盘文件;而跟它竞争的Thread-2则是监听待发送的infoList。

多次在同一个时刻,thread-0是红色的堵塞,threa-2在执行,看起来像是他们在竞争同一资源。查代码可以看到,这两个线程都会对DiskDeleteListener.pathList进行读写操作,thread-0监听到list不为空则删除磁盘文件,threa-2发送一个消息成功,则将消息的磁盘地址加入到list中。而这个pathList是一个线程安全的List,通过下面的方法构造出来的:

Java代码  
  1. DiskDeleteListener.pathList = Collections.synchronizedList(new ArrayList());

最后异常消息发送和异常磁盘监听的两个线程一直处于休眠状态。

使用visual vm 分析线程(上)相关推荐

  1. jmc线程转储_如何分析线程转储– IBM VM

    jmc线程转储 本文是我们的线程转储分析系列的第4部分,它将为您提供什么是IBM VM的JVM线程转储以及您将找到的不同线程和数据点的概述. 您将看到和学习​​到,IBM VM Thread Dump ...

  2. 如何分析线程转储– IBM VM

    本文是我们的线程转储分析系列的第4部分,它将为您概述什么是IBM VM的JVM线程转储以及您将找到的不同线程和数据点. 您将看到和学习​​到,IBM VM Thread Dump格式是不同的,但是提供 ...

  3. Java虚拟机性能监测工具Visual VM与OQL对象查询语言

    1.Visual VM多合一工具 Visual VM是一个功能强大的多合一故障诊断和性能监控的可视化工具,它集成了多种性能统计工具的功能,使用 Visual VM 可以代替jstat.jmap.jha ...

  4. JVM:如何分析线程堆栈

    英文原文:JVM: How to analyze Thread Dump 在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因.在我看来线程堆栈分析技术是Java EE产品 ...

  5. jvm线程分析命令_JVM:如何分析线程转储

    jvm线程分析命令 本文将教您如何分析JVM线程转储,并查明问题的根本原因. 以我的观点,线程转储分析是掌握Java EE生产支持的任何个人最重要的技能. 您可以从线程转储快照中获取的信息量通常远远超 ...

  6. 如何分析线程转储–线程堆栈跟踪

    本文是" 线程转储"分析系列的第5部分. 到目前为止,您已经了解了线程的基本原理以及它们与Java EE容器和JVM的交互. 您还学习了HotSpot和IBM Java VM的不同 ...

  7. JVM:如何分析线程转储

    本文将教您如何分析JVM线程转储,并查明问题的根本原因. 从我的角度来看,线程转储分析是掌握Java EE生产支持的任何个人最重要的技能. 您可以从线程转储快照中获取的信息量通常远远超出您的想象. 我 ...

  8. 可遇不可求的Question之不支持一个STA 线程上针对多个句柄的WaitAll

    不支持一个 STA 线程上针对多个句柄的 WaitAll. 题设: 在.NET开发多线程控制台程序过程中,由于业务要求,需要实现"一次扫描多笔订单",然后,通过多线程实现并发提交的 ...

  9. Intel官方对5月15号曝出的CPU侧信道漏洞“ZombieLoad”的详细技术分析(上)

    背景了解 5月15号有媒体曝出,安全研究人员在在一个月之前在Intel 芯片中发现了一种被称为"ZombieLoad"的新漏洞,此漏洞可让攻击者获取当前处理器正在处理的敏感数据. ...

最新文章

  1. 更好用的3D打印“活体”墨水来了,合成生物的新工具包!
  2. 随手记一次用C#正则表达式获取下拉菜单html标签select以及相关属性值
  3. python分布式爬虫系统_三种分布式爬虫系统的架构方式
  4. 开源力量:微软竟开源 PowerShell
  5. PHP建站环境搭建:汇总网上常见的1键安装包
  6. Python程序执行顺序
  7. java开发之路——个人开发模板之技巧
  8. svn 客户端下载地址
  9. 批量修改图幅lisp_【CAD应用技巧】批量自动修改图形文件的程序
  10. qq企业邮箱怎么删除邮件服务器,腾讯企业邮箱如何删除邮件,有什么要注意的呢?...
  11. HANA数据库备份脚本案例(刘欣)
  12. 三菱数据移位指令_三菱FX系列PLC循环与移位类指令的使用方法
  13. Win10如何彻底关闭Hyper-V(真实可用,本人亲测)
  14. 3个字节转换为另外3个字节的简单加密算法
  15. 第6-8课:分离轴算法(SAT)与碰撞检测(图文篇)
  16. fuzz对测试用例作用的一些函数
  17. Android手势识别——上下左右滑动、屏幕上下左右中区域处理
  18. Adobe Flashplayer orHTML5 Browser with WebGL or CSS3D support required 解决方案
  19. 接口文档应该如何编写
  20. 传参时带有日期参数,@JsonFormat与@DateTimeFormat

热门文章

  1. php 断点续传,php支持断点续传的文件下载类(附源码)
  2. python windows编程_在Windows下配置Python编程学习环境
  3. excel粘贴时出现故障_了解这些信息,你会知道在ESXi5.0 的虚拟化系统下文件出现故障时,我们能做些什么?...
  4. vue插槽面试题_Vue 的slot插槽 及一个奇怪的面试题
  5. linux 程序收到sigsegv信号_信号
  6. php 查oracle 表不存在报错处理,Oracle ORA-08104报错处理方法及注意事项
  7. 重庆商务学校有计算机专业吗,重庆对外经贸学院计算机科学与技术专业
  8. 苹果笔记本适合学python吗_千万别花冤枉钱!大学生买本得这么选!
  9. 使用angularJs ng-repeat做表格合并行效果
  10. python学习-Django (3)