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()
(暂时释放 stack 对象)

 

12

   

锁住 stack 对象

13

   

打印 "begin to push 0"

14

   

企图锁住 list 对象
(发现 list 已被其他线程锁住)

15

进入死锁状态

http://www.educity.cn/it/sun/201004191051041573.htm

转载于:https://www.cnblogs.com/softidea/p/4243654.html

多线程中的死锁举例与分析(转)相关推荐

  1. java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?

    转载自 java多线程中的死锁.活锁.饥饿.无锁都是什么鬼? 死锁.活锁.饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了. 死锁 死锁 ...

  2. JAVA多线程中join()方法的详细分析

    虽然关于讨论线程join()方法的博客已经非常极其特别多了,但是前几天我有一个困惑却没有能够得到详细解释,就是当系统中正在运行多个线程时,join()到底是暂停了哪些线程,大部分博客给的例子看起来都像 ...

  3. Java多线程中的死锁问题

    Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...

  4. java线程中的死锁_Java多线程中的死锁 - Break易站

    Java 多线程 synchronized关键字用于使类或方法线程安全,这意味着只有一个线程可以锁定同步方法并使用它,其他线程必须等到锁定释放并且其中任何一个获得该锁定. 如果我们的程序在多线程环境中 ...

  5. JAVA多线程中wait()方法的详细分析

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/119645679 本文出自[赵彦军的博客] 文章目录 wait 和 notify 简 ...

  6. sql server死锁_如何解决SQL Server中的死锁

    sql server死锁 In this article, we will talk about the deadlocks in SQL Server, and then we will analy ...

  7. linux系统如何查看是否是线程死锁,多线程中如何使用gdb精确定位死锁问题

    本文转载自微信公众号「程序喵大人」,作者程序喵大人 .转载本文请联系程序喵大人公众号. 在多线程开发过程中很多人应该都会遇到死锁问题,死锁问题也是面试过程中经常被问到的问题,这里介绍在c++中如何使用 ...

  8. 线程中如何使用对象_多线程中如何使用gdb精确定位死锁问题

    在多线程开发过程中很多人应该都会遇到死锁问题,死锁问题也是面试过程中经常被问到的问题,这里介绍在c++中如何使用gdb+python脚本调试死锁问题,以及如何在程序运行过程中检测死锁. 首先介绍什么是 ...

  9. java多线程同步与死锁_浅析Java多线程中的同步和死锁

    Value Engineering 1基于Java的多线程 多线程是实现并发机制的一种有效手段,它允许编程语言在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间相互独立,且与进程一样拥有独立 ...

最新文章

  1. 丁贵才130702010042第二次作业
  2. Android自动化测试之Shell脚本一——模拟触屏事件
  3. 用SRS和FFMPEG进行直播流转码
  4. 查看Linux系统版本的几种方法
  5. [云炬创业基础笔记]第五章创业机会评估测试12
  6. 给array添加元素_前囧(06篇)Array 方法详解
  7. vs 2008 Ide 设置
  8. 判断作弊 牛客 编程_牛客企业服务产品-新功能速递-第5期
  9. 截断正态分布(Truncated normal distribution)nn.init.trunc_normal_
  10. 日志中的秘密:Windows登录类型
  11. 「译文」你必须掌握的 7 种 JavaScript 错误类型
  12. 神经网络中常用激活函数总结
  13. 全国计算机信息大赛noi,全国青少年信息学竞赛NOI系列赛事汇总
  14. discuz源代码分析
  15. mybatis PageHelper.startPage出现limit错误
  16. 微信 服务器参数错误 请重新填写,微信上登录验证出现参数错误怎么解决
  17. TIA protal与SCL从入门到精通(2)——EN/ENO 机制
  18. stimulsoft mysql_StimulSoft——将炫酷的报表写入你的应用程序
  19. 基金收益率计算1:资管业务、资管产品和基金
  20. 【教程篇】Blender实例教程(一)——制作一个酷炫的三叶草星

热门文章

  1. w10 Sentinel的下载和安装
  2. @JsonIgnore和@JsonSerialize 的 区别
  3. oracle 多表查询_【Oracle】多表查询
  4. python 嵌入式数据库_Pysqlite下载 Pysqlite for Windows v2.6.3(嵌入式数据库python api 接口) 下载-脚本之家...
  5. sublime python调试_如何用sublime调试程序
  6. 华为根本没有鸿蒙系统,【图片】你看不明白的鸿蒙系统,才是华为缔造未来的“伟大”!华为并没有把系统划分为手机操作系统,我们就能知道华为想的并不是那么简单【手机吧】_百度贴吧...
  7. 的列数 获取mysql_阿里面试:MySQL如何设计索引更高效?
  8. python线程池传入多个参数_python线程池问题
  9. eclipse adt如何切换到设计界面_如何设计出优秀的UI界面?这4个方面帮你快速优化...
  10. 中文分词与马尔科夫模型之二:隐马尔科夫模型与维特比