本帖最后由 孔雀东南飞 于 2013-6-10 11:13 编辑
死锁代码:
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
synchronized(MyLock.locka)
{
System.out.println("if locka");
synchronized(MyLock.lockb)
{
System.out.println("if lockb");
}
}
}
else
{
synchronized(MyLock.lockb)
{
System.out.println("else lockb");
synchronized(MyLock.locka)
{
System.out.println("else locka");
}
}
}
}
}
class MyLock
{
static MyLock locka = new MyLock();//定义锁locka
static MyLock lockb = new MyLock();//定义锁lockb
}
class DeadLockDemo
{
public static void main(String[] args)
{
Thread t1 = new Thread(new Test(true));
Thread t2 = new Thread(new Test(false));
t1.start();
t2.start();
}
}
死锁理解:
线程t1 start()时,调用new Test(true);的run方法;
线程t2 start()时,调用new Test(false)的run方法;
这里调用的不是同一个Test对象的run方法;
锁locka 和锁lockb是唯一的,不能同时被两个线程共同使用;意思就是locka只能被线程t1或t2使用,lockb只能被线程t1或t2是使用;而不能是locka即被线程t1使用又被线程t2使用。
但是一个线程可以使用多个锁,也就是说线程t1在使用locka的同时还可以使用lockb;t2在使用locka的同时也还可以使用lockb,但某一时刻,locka或lockb只能被一个线程使用。
synchronized(locka),表示其所属线程正使用锁locka;
synchronized(lockb),表示其所属线程正使用锁lockb;
代码解析:
运行结果:
if locka
else lockb
分析:
t1.start()时, 执行到System.out.println("if locka");打印if locka; 若想继续执行synchronized(MyLock.lockb),则必须拿到lockb;
而此时,由于t2.start(),执行属于new Test(false)对象的run()方法,执行到 System.out.println("else lockb");打印else lockb;若想继续执行 synchronized(MyLock.locka),则必须拿到locka;
关键是: synchronized(MyLock.locka){}中代码还没执行完,因此t1不可能放掉锁locka;synchronized(MyLock.lockb){}中代码还没执行完,因此t2也不可能放掉lockb;而locka 和lockb只能在某一时刻被一个线程拿到,t1在拿到locka的同时还想拿到lockb,t2在拿到lockb的同时还想拿到locka,t1 t2又都不能放弃各自的锁,因此程序陷入僵局。也就是形成了死锁。
|