死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
产生死锁的原因:
1.因为系统资源不足。
2.进程运行推进的顺序不合适。
3.资源分配不当。
产生死锁的条件:
互斥条件:所谓互斥就是进程在某一时间内独占资源。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
简单的来说:死锁就是因为多线程在访问对象的时候,A线程占用了对象object1,又想去占用对象object2,但是此时的object2对象已经被B线程占用,并且B线程又想去占用object2。两个线程同时占用对方想要的对象,但是又不释放自己占有的对象,两个线程互相等待,造成拥塞无法执行下去。
public class LockDemo implements Runnable
{
private static Object object1 = new Object();
private static Object object2 = new Object();
private int flag = 0;
public static void main(String[] args)
{
LockDemo run0 = new LockDemo();
LockDemo run1 = new LockDemo();
run0.flag = 1;
run1.flag = 2;
Thread thread1 = new Thread(run0);
Thread thread2 = new Thread(run1);
thread1.start();
thread2.start();
}
@Override
public void run()
{
System.out.println(flag);
if (flag == 1)
{
synchronized (object1)
{
System.out.println("线程 : " + flag + "锁定obj1,休息0.5秒后锁定obj2去!");
try
{
Thread.sleep(500);
}
catch (Exception e)
{
e.printStackTrace();
}
synchronized (object2)
{
System.out.println("线程 : " + flag + "访问 object2");
}
}
}
if (flag == 2)
{
synchronized (object2)
{
System.out.println("线程 : " + flag + "锁定obj2,休息0.5秒后锁定obj1去!");
try
{
Thread.sleep(500);
}
catch (Exception e)
{
e.printStackTrace();
}
synchronized (object1)
{
System.out.println("线程 : " + flag + "访问object1");
}
}
}
}
}
执行结果
1
2
线程 : 2锁定obj2,休息0.5秒后锁定obj1去!
线程 : 1锁定obj1,休息0.5秒后锁定obj2去!
从执行的结果我们发现,每个线程都没有执行
System.out.println("线程 : " + flag + "访问object");
因为线程1执行代码时把object1的时候加锁,然后去访问object2,但是此时的object2已经被线程2加上了锁,线程1和线程2分别占用object1和object2,又想去访问对方的占用的对象,显然是不可行的。就好比两个小孩交换玩具,一个小孩说:你先把玩具给我,我再把玩具给你,另外一个小孩说:不行,你要先把你的玩具给我,我再给你。结果两个小孩谁也不愿给谁,自然而然地在那僵持着。
在代码中在修饰object对象的时候,使用了static关键字,如果不使用static 关键字的执行结果是什么样的呢?
1
线程 : 1锁定obj1,休息0.5秒后锁定obj2去!
2
线程 : 2锁定obj2,休息0.5秒后锁定obj1去!
线程 : 2访问object1
线程 : 1访问 object2
可以看到并没有发生死锁,为什么?是因为使用static 关键字的时,两个object是公共的,不使用关键字时,两个object是线程自己用了两个独立的对象。同样我们打个比方,使用static关键修饰的object对象,就好比幼儿园中共有的两个玩具,大家谁都可以玩,但是每个小孩,都只能同时拥有一个。一个小朋友要是想要玩另外一个小朋友的玩具,必须要俩人互相交换。不用static关键字修饰的object对象,就好比每个小朋友自己带玩具来玩,不是共有的,我想玩哪个就玩哪个。
来源:oschina
链接:https://my.oschina.net/u/1589583/blog/373058