多线程中的死锁举例与分析(转)
1. 一个特殊构造的程序
考虑下面这个专门为说明多线程中的死锁现象而构造的程序:
import java.util.LinkedList;public class Stack {public static void main(String[] args) {final Stack stack = new Stack();new Thread("push") {@Overridepublic void run() {for (int i = 0; i < 100; i++) {try {Thread.sleep(10);//to make the deadlock occur} catch (InterruptedException e) {}stack.push("object " + i);}}}.start();new Thread("pop") {@Overridepublic void run() {for (int i = 0; i < 100; i++) {try {System.out.println(stack.pop());} catch (Exception e) {}}}}.start();}LinkedList<Object> list = new LinkedList<Object>();public synchronized void push(Object x) {System.out.println("begin to push " + x);synchronized (list) {list.addLast(x);notify();}System.out.println("end to push " + x);}public synchronized Object pop() throws Exception {System.out.println("begin to pop");synchronized (list) {if (list.size() <= 0) {wait();}return list.removeLast();}}}
该程序构造了一个 Stack,启动了两个线程。一个线程向 Stack 中添加数据,另外一个线程从 Stack 中取出数据并打印。
但是运行程序后就会发现程序输出:
begin to pop begin to push object 0
后,在再也没有后续输出了。
2. Dump 并分析线程状态
启动 jvisualvm 查看该程序线程的状态,将其 Dump,就可以得到以下线程堆栈信息:
"pop" prio=6 tid=0x00c00000 nid=0x2b0 in Object.wait() [0x00f9f000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x27f65648> (a loggerlock.Stack)at java.lang.Object.wait(Object.java:485)at loggerlock.Stack.pop(Stack.java:49)- locked <0x27f65658> (a java.util.LinkedList)- locked <0x27f65648> (a loggerlock.Stack)at loggerlock.Stack$2.run(Stack.java:26)Locked ownable synchronizers:- None"push" prio=6 tid=0x00bfec00 nid=0x14c8 waiting for monitor entry [0x00f4f000]java.lang.Thread.State: BLOCKED (on object monitor)at loggerlock.Stack.push(Stack.java:39)- waiting to lock <0x27f65658> (a java.util.LinkedList)- locked <0x27f65648> (a loggerlock.Stack)at loggerlock.Stack$1.run(Stack.java:16)Locked ownable synchronizers:- None
可以看到,pop 线程正在运行 wait(); 语句,处于 WAITING 状态,同时,该线程锁住了 list 和 stack 对象。
push 线程处于 BLOCKED 状态,等待其他线程释放 list 对象。
3. 运行过程及死锁原因分析
步骤 |
主程序 |
pop 线程 |
push 线程 |
1 |
启动 |
||
2 |
创建 stack 对象 |
||
3 |
创建 list 对象 |
||
4 |
启动 |
||
5 |
启动 |
||
6 |
sleep 10ms |
||
7 |
调用 stack.pop() |
||
8 |
锁住 stack 对象 |
||
9 |
打印 "begin to pop" |
||
10 |
锁住 list 对象 |
||
11 |
调用 stack.wait() |
||
12 |
锁住 stack 对象 |
||
13 |
打印 "begin to push 0" |
||
14 |
企图锁住 list 对象 |
||
15 |
进入死锁状态 |
http://www.educity.cn/it/sun/201004191051041573.htm
转载于:https://www.cnblogs.com/softidea/p/4243654.html
多线程中的死锁举例与分析(转)相关推荐
- java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?
转载自 java多线程中的死锁.活锁.饥饿.无锁都是什么鬼? 死锁.活锁.饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了. 死锁 死锁 ...
- JAVA多线程中join()方法的详细分析
虽然关于讨论线程join()方法的博客已经非常极其特别多了,但是前几天我有一个困惑却没有能够得到详细解释,就是当系统中正在运行多个线程时,join()到底是暂停了哪些线程,大部分博客给的例子看起来都像 ...
- Java多线程中的死锁问题
Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...
- java线程中的死锁_Java多线程中的死锁 - Break易站
Java 多线程 synchronized关键字用于使类或方法线程安全,这意味着只有一个线程可以锁定同步方法并使用它,其他线程必须等到锁定释放并且其中任何一个获得该锁定. 如果我们的程序在多线程环境中 ...
- JAVA多线程中wait()方法的详细分析
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/119645679 本文出自[赵彦军的博客] 文章目录 wait 和 notify 简 ...
- sql server死锁_如何解决SQL Server中的死锁
sql server死锁 In this article, we will talk about the deadlocks in SQL Server, and then we will analy ...
- linux系统如何查看是否是线程死锁,多线程中如何使用gdb精确定位死锁问题
本文转载自微信公众号「程序喵大人」,作者程序喵大人 .转载本文请联系程序喵大人公众号. 在多线程开发过程中很多人应该都会遇到死锁问题,死锁问题也是面试过程中经常被问到的问题,这里介绍在c++中如何使用 ...
- 线程中如何使用对象_多线程中如何使用gdb精确定位死锁问题
在多线程开发过程中很多人应该都会遇到死锁问题,死锁问题也是面试过程中经常被问到的问题,这里介绍在c++中如何使用gdb+python脚本调试死锁问题,以及如何在程序运行过程中检测死锁. 首先介绍什么是 ...
- java多线程同步与死锁_浅析Java多线程中的同步和死锁
Value Engineering 1基于Java的多线程 多线程是实现并发机制的一种有效手段,它允许编程语言在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间相互独立,且与进程一样拥有独立 ...
最新文章
- 丁贵才130702010042第二次作业
- Android自动化测试之Shell脚本一——模拟触屏事件
- 用SRS和FFMPEG进行直播流转码
- 查看Linux系统版本的几种方法
- [云炬创业基础笔记]第五章创业机会评估测试12
- 给array添加元素_前囧(06篇)Array 方法详解
- vs 2008 Ide 设置
- 判断作弊 牛客 编程_牛客企业服务产品-新功能速递-第5期
- 截断正态分布(Truncated normal distribution)nn.init.trunc_normal_
- 日志中的秘密:Windows登录类型
- 「译文」你必须掌握的 7 种 JavaScript 错误类型
- 神经网络中常用激活函数总结
- 全国计算机信息大赛noi,全国青少年信息学竞赛NOI系列赛事汇总
- discuz源代码分析
- mybatis PageHelper.startPage出现limit错误
- 微信 服务器参数错误 请重新填写,微信上登录验证出现参数错误怎么解决
- TIA protal与SCL从入门到精通(2)——EN/ENO 机制
- stimulsoft mysql_StimulSoft——将炫酷的报表写入你的应用程序
- 基金收益率计算1:资管业务、资管产品和基金
- 【教程篇】Blender实例教程(一)——制作一个酷炫的三叶草星
热门文章
- w10 Sentinel的下载和安装
- @JsonIgnore和@JsonSerialize 的 区别
- oracle 多表查询_【Oracle】多表查询
- python 嵌入式数据库_Pysqlite下载 Pysqlite for Windows v2.6.3(嵌入式数据库python api 接口) 下载-脚本之家...
- sublime python调试_如何用sublime调试程序
- 华为根本没有鸿蒙系统,【图片】你看不明白的鸿蒙系统,才是华为缔造未来的“伟大”!华为并没有把系统划分为手机操作系统,我们就能知道华为想的并不是那么简单【手机吧】_百度贴吧...
- 的列数 获取mysql_阿里面试:MySQL如何设计索引更高效?
- python线程池传入多个参数_python线程池问题
- eclipse adt如何切换到设计界面_如何设计出优秀的UI界面?这4个方面帮你快速优化...
- 中文分词与马尔科夫模型之二:隐马尔科夫模型与维特比