黑马程序员_日记16_Java多线程(六)
2015-03-28 16:02
351 查看
——- android培训、java培训、期待与您交流! ———-
两个线程分别持有一个资源,
并同时请求得到对方的资源。
在这种情况下产生的不正常情况就叫做死锁。
死锁在什么情况下会发生呢?
死锁在同步嵌套同步的情况下会发生。
至少有2把锁,才会产生死锁。
运行结果见下图
如图所示,票额为1000张,但是卖到984的时候就卡主动不了了,
说明发生了死锁。
运行结果
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-1在else中拿到了lockb锁…..
结果显示:当线程Thread-1刚跑起来,就立刻造成了死锁
避免死锁的发生,这样才能保证程序的安全性。
死锁
一、基本概念
死锁是什么呢?两个线程分别持有一个资源,
并同时请求得到对方的资源。
在这种情况下产生的不正常情况就叫做死锁。
死锁在什么情况下会发生呢?
死锁在同步嵌套同步的情况下会发生。
至少有2把锁,才会产生死锁。
二、死锁实例1
首先,以前面售票的例子展示一下死锁。class Ticket implements Runnable { private int tick = 1000; Object obj = new Object(); boolean flag = true; public void run() { if(flag) { while(true) { synchronized(obj) { show(); } } } else while(true) show(); } public synchronized void show()//this { synchronized(obj) { if(tick>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"....code : "+ tick--); } } } } class DeadLockDemo { public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); try{Thread.sleep(10);}catch(Exception e){} t.flag = false; t2.start(); } }
运行结果见下图
如图所示,票额为1000张,但是卖到984的时候就卡主动不了了,
说明发生了死锁。
三、死锁实例2
下面我自己写了一个简答的例子,来测试死锁。//建立一个锁类,注意:锁就是对象,在这里使用Object类的对象 class MyLock { //建立两把锁,注意为了调用方便,使用static修饰 static Object locka = new Object(); static Object lockb = new Object(); } //建立一个会产生死锁的类 class MyDeadLock implements Runnable { //设置一个标识来让两个线程各自执行一部分代码 private boolean flag; //利用构造函数传递标识 MyDeadLock(boolean flag) { this.flag = flag; } //覆盖run方法 public void run() { //如果标识为true,则该线程执行if部分代码 if(flag==true) { //让程序一直转,直到死锁 while(true) { //利用同步代码块嵌套同步代码快制造死锁 //因为static修饰了锁,所以可以直接用类名.锁,直接调用对象 synchronized(MyLock.locka) { //表示线程在if语句中拿到了locka锁 System.out.println("线程:"+Thread.currentThread().getName()+"在if中拿到了 locka.锁......"); synchronized(MyLock.lockb) { //表示线程在if语句拿到了lockb锁 System.out.println("线程:"+Thread.currentThread().getName()+"在if中拿到了 lockb锁......"); } } } } //否则执行else的这部分代码 else { //让程序一直转,直到死锁 while(true) { //利用同步代码块嵌套同步代码快制造死锁 synchronized(MyLock.lockb) { //表示线程在else语句中拿到了lockb锁 System.out.println("线程:"+Thread.currentThread().getName()+"在else中拿到了lockb锁....."); synchronized(MyLock.locka) { //表示线程在else语句拿到了locka锁 System.out.println("线程:"+Thread.currentThread().getName()+"在else中拿到了lockb锁....."); } } } } } } class MyDeadLockDemo { public static void main(String[] args) { //通过线程类建立线程对象,并将实现了接口Runnable类的对象作为实际参数传递进去 Thread t1 = new Thread(new MyDeadLock(true)); Thread t2 = new Thread(new MyDeadLock(false)); //调用start方法,启动线程1 t1.start(); //为了让程序多运行一会儿再死锁 try{Thread.sleep(10);}catch(Exception e){} //调用start方法,启动线程1 t2.start(); } }
运行结果
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-0在if中拿到了 lockb锁……
线程:Thread-0在if中拿到了 locka.锁……
线程:Thread-1在else中拿到了lockb锁…..
结果显示:当线程Thread-1刚跑起来,就立刻造成了死锁
四、小结
在了解了死锁的原理之后,以后下程序的时候就一定注意避免死锁的发生,这样才能保证程序的安全性。
相关文章推荐
- 黑马程序员_日记14_Java多线程(四)
- 黑马程序员_日记18_Java多线程(八)--生产者消费者问题JDK1.5特性
- 黑马程序员--java多线程和单例模式--java学习日记3(基础知识)
- 黑马程序员——java基础日记——多线程(2)——线程间通信与JDK1.5新特性
- 黑马程序员_Java学习日记6_多线程
- 黑马程序员Java学习日记(3)异常,String,多线程
- 黑马程序员——学习日记11 java多线程
- 黑马程序员--Java学习日记之多线程
- 黑马程序员_日记19_Java多线程(九)
- 黑马程序员--Java学习日记6_多线程
- 黑马程序员Java基础加强9-16学习日记
- 黑马程序员_Java学习日记16_IO流4
- 黑马程序员_ JAVA学习日记—JAVA中的多线程
- 黑马程序员——学习日记16 java IO流 (中)
- 黑马程序员——java基础日记——多线程(1)
- 黑马程序员_JAVA学习日记_JAVA中的多线程补充
- 黑马程序员——Java语言基础——04.多线程(2)线程间通信
- 黑马程序员_日记1--Java函数
- 黑马程序员——Java基础——多线程(二)
- 黑马程序员——Java基础---理解多线程