您的位置:首页 > 职场人生

黑马程序员_日记16_Java多线程(六)

2015-03-28 16:02 351 查看
 ——- android培训java培训、期待与您交流! ———-

死锁

一、基本概念

死锁是什么呢?

两个线程分别持有一个资源,

并同时请求得到对方的资源。

在这种情况下产生的不正常情况就叫做死锁。

死锁在什么情况下会发生呢?

死锁在同步嵌套同步的情况下会发生。

至少有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刚跑起来,就立刻造成了死锁

四、小结

在了解了死锁的原理之后,以后下程序的时候就一定注意

避免死锁的发生,这样才能保证程序的安全性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 死锁