——- 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刚跑起来,就立刻造成了死锁
四、小结
在了解了死锁的原理之后,以后下程序的时候就一定注意
避免死锁的发生,这样才能保证程序的安全性。
时间: 2024-10-11 06:48:42