b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

java多线程死锁 Java问题定位之Java线程堆栈分析(2)

电脑杂谈  发布时间:2017-12-25 23:02:23  来源:网络整理

从上面的main线程看,线程堆栈里面的最直观的信息是当前线程的调用上下文,即从哪个函数调用到哪个函数(从下往上看),正执行到哪一类的哪一行,借助这些信息,我们就对当前系统正在做什么一目了然。

另外,从main线程的堆栈中,有-locked<0xc8c1a090>(a java.lang.Object) 语句,这表示该线程已经占用了锁,其中0xc8c1a090表示锁ID,这个锁ID是系统自动生成的,我们只需要知道每次打印堆栈,同一个ID表示是同一个锁即可

其中"线程对应的本地线程Id号"所指的本地线程是指该java虚拟机所对应的虚拟机中的本地线程,我们知道java是解析型语言,执行的实体是java虚拟机,因此java代码是依附于java虚拟机的本地线程执行的,之前文章中讲过,当启动一个线程时,是创建一个native本地线程,本地线程才是真实的线程实体,为了更加深入理解本地线程和java线程的关系,我们可以通过以下方式将java虚拟机的本地线程打印出来:

1、试用ps -ef|grep java 获得java进行id

2、试用pstack<java pid> 获得java虚拟机本地线程的堆栈

从操作系统打印出来的虚拟机的本地线程看,本地线程数量和java线程数量是相同的,说明二者是一一对应的关系。

我们获取的本地线程堆栈如下:

这个本地线程号如何与java线程堆栈文件对应起来呢,每一个线程都有tid,nid的属性,通过这些属性可以对应相应的本地线程,我们先看java线程第一行,里面有一个属性是nid,

其中nid是native thread id,也就是本地线程中的LWPID,二者是相同的,只不过java线程中的nid用16进制表示,本地线程的id用十进制表示。3368的十六进制表示0xd28,在java线程堆栈中查找nid为0xd28就是本地线程对应的java线程。

在介绍线程堆栈的解读方法之前,先介绍一点关于多线程的知识,即wait和sleep的重要区别。wait和sleep有一个共同点,就是二者都把当前线程阻塞住,我们叫睡眠或等待,二者有着本质区别:

wait() 当线程执行到wait()方法上,当前线程会释放监视锁,此时其他线程可以占有该锁,一旦wait()方法执行完成,当前线程继续持有该锁,直到执行完锁的作用域。结合notify(),可以实现两个线程之间的通信,一个线程可以通过这种方法通知另一个线程继续执行,完成线程之间的配合。wait()锁的

java多线程应用场景_java多线程死锁_java线程死锁怎么解决

在wait(5000)这个期间,当前线程会释放它占用的锁,其他线程有机会获得到该锁,当wait(5000)结束后,当前线程继续获取该锁的使用权。满足以下条件之一,wait退出:

1、达到等待时间之后,自动退出

2、其他线程调用了该锁的notify方法,如果多个线程在等待同一个锁,只有一个线程会被通知到。

sleep() 和锁操作无关,如果该方法恰好在一个锁的保护范围内,当前线程即使执行sleep的时候,仍然保持监视锁。

sleep方法是线程的一个静态方法,实际上和锁操作无关,不会产生特别的锁,如果原来持有,现在仍然持有,如果原来没有,现在仍然没有。

从上面介绍的线程堆栈看,线程堆栈中包含直接信息为:线程个数,每个线程调用的方法堆栈,当前锁的状态。从线程个数可以直接数出来,线程调用的方法堆栈,从下向上看,表示了当前线程调用哪个类哪个方法,锁的状态看起来需要一些技巧,与锁相关的重要信息如下:

当一个线程占有一个锁的时候,线程堆栈会打印一个-locked<0x22bffb60>


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-55884-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    每日福利
    热点图片
    拼命载入中...