当我们为了线程安全而加锁的时候,可能一不注意就造成了死锁。
比如下面这样:
package cn.liz.threaddemo; public class ThreadDeadlock{ public static void main(String[] args) { Object obj1 = new Object(); Object obj2 = new Object(); // 在线程A中可能在某个时候 持有A和B两个对象的锁 new A(obj1,obj2).start();
new B(obj1,obj2).start();// 在线程A中可能在某个时候 持有A和B两个对象的锁
//
}}
class A extends Thread{
Object obj1;
Object obj2;
public A(){
}
public A(Object obj1, Object obj2) {
super();
this.obj1 = obj1;
this.obj2 = obj2;
}
public void run(){
// 在obj1锁中同样持有obj2的锁
synchronized(obj1){
try {
Thread.sleep(200);
}
catch (InterruptedException e)
{e.printStackTrace();}// 这样可能导致的问题是 方法持有两个锁,且都释放synchronized (obj2) {}
// A 不释放obj1时,释放obj2
}System.out.println("给我烟");}
}class B extends Thread{
Object obj1;
Object obj2;
public B() {super();}public B(Object obj1, Object obj2) {super();
this.obj1 = obj1;
this.obj2 = obj2;
}public void run(){
synchronized(obj2){
try {
// 模拟实际的网络延时造成的 同时持有两个对象的锁 互不释放
Thread.sleep(200);}
catch (InterruptedException e) {
e.printStackTrace();
}synchronized (obj1) {}
// B 想要拿到obj2对象,但是A一直要B锁住的obj1对象,因此二者都拿着一个对象要对方手中的对象,互不相让}System.out.println("给我钱");}}
思考下上面的代码,是什么造成了死锁呢?不难发现,是因为我们在一个锁中,同时锁住了另外一个东西,那么在实际的操作中,由于网络延时的问题,就可能造成同时持有两个对象的锁,彼此互不释放。
这样就造成了死锁。
避免死锁的方式可以是,尽量少用锁的嵌套,以及在一个方法中,尽量只建立一个锁。