- 浏览: 515048 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (114)
- C基础 (1)
- C指针 (0)
- C语言库函数相关 (1)
- Linux (2)
- Linux网络编程 (1)
- PostgreSQL (0)
- Redis (2)
- Java Web (2)
- JAVA基础 (35)
- Ubuntu (8)
- Android (2)
- MySQL (3)
- 日志 (1)
- 书虫 (1)
- 数据结构 (0)
- 算法 (0)
- 开发工具 (1)
- 转载 (13)
- 英语 (18)
- tomcat启动脚本分析 (3)
- Oracle基础 (4)
- tomcat源码分析 (3)
- tomcat (1)
- Java相关 (1)
- Oracle基本原理--Oracle体系结构 (0)
- Oracle基本原理--表 (0)
- Oracle基本原理--索引 (0)
- Oracle基本原理--事务 (0)
- Oracle开发--SQL (1)
- Oracle基本原理--PL/SQL (0)
- Oracle基本原理--常用函数 (0)
- Oralce管理--用户及权限管理 (0)
- Oracle管理--安装调试 (0)
- Oracle管理--备份恢复 (0)
- Oralce管理--数据迁移 (0)
- Oracle管理--闪回 (0)
- Oracle管理--故障处理 (0)
- Oracle优化原理--统计信息 (0)
- Oracle优化原理--执行计划 (0)
- Oracle优化原理--诊断工具 (0)
- Oracle优化原理--深入理解表 (0)
- Oracle优化原理--深入理解索引 (0)
- Oracle优化原理--表连接原理 (0)
- Java--OOP (0)
- Java--异常 (0)
- Java--泛型 (0)
- Java--集合 (0)
- Java--IO (0)
- Java--枚举类型 (0)
- Java--注释 (0)
- Java--多线程 (0)
- Java--XML (0)
- Java--JDBC (3)
- Servlet (0)
- JSP (0)
- JSTL (0)
- 设计模式 (0)
- DAO与MVC (0)
- Javascript (2)
- Ajax (0)
- JQuery (0)
- HTML/CSS (0)
- 前端相关 (1)
- HTTP (0)
- TCP/IP (0)
- GO基础 (0)
最新评论
-
jsonmong:
推荐一个开发平台,采用的是插件化的设计思想,效果很不错的。ht ...
构建Java Web开发环境 -
wxm198427:
首先表示辛苦了!我想问个问题:我的是windows 7 x64 ...
Oracle 11g R2 for Win7旗舰版(64位)的安装步骤 -
握着橄榄枝的人:
我之前按照你的update mysql.user set pa ...
Windows7下MySQL5.5.20免安装版的配置 -
confident_f:
安装了32的客户端后,用plsql导入导出表有问题,生成不了d ...
Oracle 11g R2 for Win7旗舰版(64位)的安装步骤 -
confident_f:
安装数据库的时候第9步卡住了 是怎么回事呢?
Oracle 11g R2 for Win7旗舰版(64位)的安装步骤
当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚拟机没有监测,也没有采用措施来处理死锁情况,所以多线程编程时应该采取措施避免死锁的出现。一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程都处于阻塞状态,无法继续运行。
死锁是很容易发生的,尤其在系统中出现多个同步监视器的情况下,如下程序将会出现死锁:
源代码:DeadLock.java
程序运行的结果如下:
当前线程名:主线程进入了A实例的foo方法
当前线程名:副线程进入了B实例的bar方法
当前线程名:主线程企图调用实例B的last方法
当前线程名:副线程企图进入实例A的last方法
从上述结果可以看出,程序既无法向下执行,也不会抛出任何异常,将一直“僵持”着无法向下执行。这是因为:上面的程序中A对象和B对象的方法都是同步方法,也就是A对象和B对象都是同步锁。程序中有两条线程执行,一条线程的线程执行体是DeadLock类的run()方法,另一个线程的执行体是DeadLock类的init()方法(主线程调用了init()方法)。其中run()方法中让B对象调用bar()方法,而init()方法中让A对象调用foo()方法。结果显示:init方法先执行,调用了A对象的foo方法,进入foo方法之前,该线程对A对象加锁——当程序执行到(1)号代码时,主线程暂停200ms;CPU切换到执行另一条线程,让B对象执行bar方法,所以上面的结果中可以看到副线程开始执行B实例的bar方法,进入bar方法之前,该线程对B对象加锁——当程序执行到(2)号代码时,副线程也暂停200ms;接下来,主线程会先醒过来,继续向下执行,直到(3)号代码处希望调用B对象的last方法——执行该方法之前必须先对B对象加锁,但此时副线程正保持着B对象的锁,所以主线程阻塞;接下来,副线程应该也醒过来了,继续向下执行,直到(4)号代码处希望调用A对象的last方法——执行该方法之前必须先对A对象加锁,但此时主线程正保持着A对象的锁——至此就出现了主线程保持着A对象的锁,等待对B对象的加锁,而副线程保持着B对象的锁,等待对A对象的加锁,两条线程相互等待对方先释放,所以就出现了死锁。
死锁是很容易发生的,尤其在系统中出现多个同步监视器的情况下,如下程序将会出现死锁:
源代码:DeadLock.java
class A{ public synchronized void foo(B b){ System.out.println("当前线程名:"+Thread.currentThread().getName()+"进入了A实例的foo方法");//(1) try{ Thread.sleep(200); } catch(InterruptedException ie){ ie.printStackTrace(); } System.out.println("当前线程名:"+Thread.currentThread().getName()+"企图调用实例B的last方法");//(3) b.last(); } public synchronized void last(){ System.out.println("进入了A类的last方法内部"); } } class B{ public synchronized void bar(A a){ System.out.println("当前线程名:"+Thread.currentThread().getName()+"进入了B实例的bar方法");//(2) try{ Thread.sleep(200); } catch(InterruptedException ie){ ie.printStackTrace(); } System.out.println("当前线程名:"+Thread.currentThread().getName()+"企图进入实例A的last方法");//(4) a.last(); } public synchronized void last(){ System.out.println("进入了B类的last方法内部"); } } public class DeadLock implements Runnable{ A a = new A(); B b = new B(); public void init(){ Thread.currentThread().setName("主线程"); a.foo(b); System.out.println("进入了主线程之后"); } public void run(){ Thread.currentThread().setName("副线程"); b.bar(a); System.out.println("进入了副线程之后"); } public static void main(String args[]){ DeadLock d1 = new DeadLock(); new Thread(d1).start(); d1.init(); } }
程序运行的结果如下:
当前线程名:主线程进入了A实例的foo方法
当前线程名:副线程进入了B实例的bar方法
当前线程名:主线程企图调用实例B的last方法
当前线程名:副线程企图进入实例A的last方法
从上述结果可以看出,程序既无法向下执行,也不会抛出任何异常,将一直“僵持”着无法向下执行。这是因为:上面的程序中A对象和B对象的方法都是同步方法,也就是A对象和B对象都是同步锁。程序中有两条线程执行,一条线程的线程执行体是DeadLock类的run()方法,另一个线程的执行体是DeadLock类的init()方法(主线程调用了init()方法)。其中run()方法中让B对象调用bar()方法,而init()方法中让A对象调用foo()方法。结果显示:init方法先执行,调用了A对象的foo方法,进入foo方法之前,该线程对A对象加锁——当程序执行到(1)号代码时,主线程暂停200ms;CPU切换到执行另一条线程,让B对象执行bar方法,所以上面的结果中可以看到副线程开始执行B实例的bar方法,进入bar方法之前,该线程对B对象加锁——当程序执行到(2)号代码时,副线程也暂停200ms;接下来,主线程会先醒过来,继续向下执行,直到(3)号代码处希望调用B对象的last方法——执行该方法之前必须先对B对象加锁,但此时副线程正保持着B对象的锁,所以主线程阻塞;接下来,副线程应该也醒过来了,继续向下执行,直到(4)号代码处希望调用A对象的last方法——执行该方法之前必须先对A对象加锁,但此时主线程正保持着A对象的锁——至此就出现了主线程保持着A对象的锁,等待对B对象的加锁,而副线程保持着B对象的锁,等待对A对象的加锁,两条线程相互等待对方先释放,所以就出现了死锁。
发表评论
-
foreach循环
2013-06-24 16:15 1433从JDK1.5开始,Java提供了一个更简单的循环:forea ... -
可变参数
2013-06-24 15:38 1193从JDK1.5开始,Java允许使用可变参数为方法指定数量不确 ... -
泛型(core java 笔记)
2013-06-18 16:18 20201.为什么引入泛型 package generic; ... -
两个程序的说明
2010-10-19 09:26 11301、程序1的结果是: clas ... -
构造器初始化
2010-10-18 14:42 1477可以用构造器来进行初始化。在运行时刻,可以调用方法或执行某些动 ... -
成员初始化
2010-10-18 07:55 1195Java尽力保证:所有变量在使用前都能得到恰当的初始化。 对 ... -
线程的同步
2010-10-11 19:00 1246一个经典的关于线程安全性的问题:银行取钱问题。 银行取钱的基 ... -
java网站收集
2010-10-10 18:13 1225JAVA开发者最常去的25个英文网站:http://www.i ... -
控制线程
2010-10-10 16:06 19871、线程睡眠:sleep 如果我们需要让当前正在执行的线程暂 ... -
线程的状态
2010-09-28 19:00 995线程从创建到执行完毕的整个过程称为线程的生命周期,在整个生命周 ... -
Java中Thread类的start()和run()的区别
2010-09-27 15:33 40771、start()方法来启动线程,真正实现了多线程运行,这时无 ... -
Java中创建线程的两种方法
2010-09-26 10:18 5609在Java中创建线程有两种方法:继承Thread类和实现Run ... -
创建String对象过程的内存分配小结
2010-09-23 20:32 2744常量池(Constant Pool):指的是在编译期被确定,并 ... -
Java堆和栈的区别 经典总结(转载)
2010-09-18 16:48 1239栈与堆都是Java用来在Ram中存放数据的地方。 与C++不 ... -
Java初学者都必须理解的七大问题
2010-09-18 10:36 1097问题一:我声明了什么 ... -
关于计算java程序运行时间(转载)
2010-09-18 09:22 1090//第一种,伪代码 long startTime= ... -
for循环的优化
2010-09-17 20:29 2107在程序中经常用到for循环,当一些算法实时性要求非常高时,对f ... -
详细解析Java中抽象类和接口的区别(转载)
2010-09-17 10:16 1074在Java语言中,abstract class和inter ... -
集合类(四):Map集合
2010-09-16 20:26 21205、Map集合 Map集合为映射类型,映射与集和列表有明显的区 ... -
集合类(三):Set集合
2010-09-16 19:43 28714、Set集合 Set集合为集类型,集是最简单的一种集合,存放 ...
相关推荐
检测线程死锁,告诉你如何检测线程死锁,学习一下吧
有简单的控制台例子理解线程死锁的概念。并且理解线程是轮换CPU时间片的。
实测有效的一个c++检测线程死锁的解决方法(实现和测试代码) 原创实测有效的一个c++检测线程死锁的解决方法,已应用于项目,实测有效 原创文章地址:https://blog.csdn.net/liaozhilong88/article/details/80354414...
java多线程死锁预防机制研究,java多线程死锁预防机制研究
Linux系统线程死锁实验报告.pdf
DllMain和多线程死锁[归类].pdf
明白死锁产生的原因,在程序中演示死锁产生并从而实现多线程陈旭解决死锁(deadlock)这一类问题。
lookcop 线程死锁检测工具
java线程实践,了解线程死锁,同步问题
线程死锁 CPU过高 WeakHashMap 请求原因分析
死锁问题,java多线程死锁
本资源为多线程中,多线程共享资源,出现死锁的情况。浅显易懂
通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间等方面的特点,并掌握线程与进程的区别。
关于在类的构造函数和析构使用临界区函数导致的多线程死锁的一个经验之谈
定位进程中线程死锁检测工具
一个简单有效的即时检测线程死锁的方法(附c++源代码) 原文链接:https://blog.csdn.net/liaozhilong88/article/details/80354414 原链接是windows下实现,这份代码以pthread简单实现跨平台 感谢原博主分享
死锁是一种情况,其中两个或多个线程(或进程)相互等待对方释放资源,导致它们都无法继续执行。这是一种非常令人头疼的问题,因为它可以导致...本文中会详细讲述linux、Windows下调试C++线程死锁、Qt线程死锁的方式。
多线程死锁,活锁,竞争锁问题总结。举例分析产生各种锁的原因以及解决方法
什么是线程死锁 是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。 线程死锁怎么发生 发生死锁的情况一般是两个对象的锁相互等待造成的。 死锁...