博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java知多少(64)线程死锁
阅读量:6680 次
发布时间:2019-06-25

本文共 2373 字,大约阅读时间需要 7 分钟。

需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象X的管程而另一个线程进入了对象Y的管程。如果X的线程试图调用Y的同步方法,它将像预料的一样被锁定。而Y的线程同样希望调用X的一些同步方法,线程永远等待,因为为到达X,必须释放自己的Y的锁定以使第一个线程可以完成。死锁是很难调试的错误,因为:

  • 通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
  • 它可能包含多于两个的线程和同步对象(也就是说,死锁在比刚讲述的例子有更多复杂的事件序列的时候可以发生)。

为充分理解死锁,观察它的行为是很有用的。下面的例子生成了两个类,A和B,分别有foo( )和bar( )方法。这两种方法在调用其他类的方法前有一个短暂的停顿。主类,名为Deadlock,创建了A和B的实例,然后启动第二个线程去设置死锁环境。foo( )和bar( )方法使用sleep( )强迫死锁现象发生。

1 // An example of deadlock. 2 class A { 3     synchronized void foo(B b) { 4         String name = Thread.currentThread().getName(); 5         System.out.println(name + " entered A.foo"); 6         try { 7             Thread.sleep(1000); 8         } catch(Exception e) { 9             System.out.println("A Interrupted");10         }11         System.out.println(name + " trying to call B.last()");12         b.last();13     }14     synchronized void last() {15         System.out.println("Inside A.last");16     }17 }18 class B {19     synchronized void bar(A a) {20         String name = Thread.currentThread().getName();21         System.out.println(name + " entered B.bar");22         try {23             Thread.sleep(1000);24         } catch(Exception e) {25             System.out.println("B Interrupted");26         }27         System.out.println(name + " trying to call A.last()");28         a.last();29     }30     synchronized void last() {31         System.out.println("Inside A.last");32     }33 }34 class Deadlock implements Runnable {35     A a = new A();36     B b = new B();37     Deadlock() {38         Thread.currentThread().setName("MainThread");39         Thread t = new Thread(this, "RacingThread");40         t.start();41         a.foo(b); // get lock on a in this thread.42         System.out.println("Back in main thread");43     }44     public void run() {45         b.bar(a); // get lock on b in other thread.46         System.out.println("Back in other thread");47     }48     public static void main(String args[]) {49         new Deadlock();50     }51 }

运行程序后,输出如下:

MainThread entered A.foo

RacingThread entered B.bar
MainThread trying to call B.last()
RacingThread trying to call A.last()
因为程序死锁,你需要按CTRL-C来结束程序。在PC机上按CTRL-BREAK(或在Solaris下按CTRL-\)你可以看到全线程和管程缓冲堆。你会看到RacingThread在等待管程a时占用管程b,同时,MainThread占用a等待b。该程序永远都不会结束。像该例阐明的,你的多线程程序经常被锁定,死锁是你首先应检查的问题。

系列文章:

转载于:https://www.cnblogs.com/Coda/p/4507307.html

你可能感兴趣的文章
MySQL数据库操作个人手记
查看>>
我的友情链接
查看>>
泡沫学员CSS切图学习总结
查看>>
centos 学习日记 文件隐藏属性 chattr lsattr
查看>>
redhat yum 失败
查看>>
log4j2日志框架使用简单概述
查看>>
新手处理事故之误删boot目录以及更严重的删除操作
查看>>
bootstap-table 只显示列名和表格不显示数据
查看>>
linux 网站架设调优Apache(四)
查看>>
vi的使用
查看>>
当你需要处理XML文档时
查看>>
【Python之旅】第五篇(一):Python Socket通信原理
查看>>
pycharm 5注册
查看>>
java-buildpack源码分析之Release
查看>>
iptables实现网络防火墙及地址转换
查看>>
Objective-C基础语法规则教程
查看>>
fiddler的使用
查看>>
Spring事务5种属性
查看>>
css图片对齐排版思路
查看>>
如何将sql 2000数据库 移植到 mysql 数据库中
查看>>