Java线程死锁

死锁(DeadLock):指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程.
一、死锁现象
例如:两个线程t1、t2分别需要两个对象obj1、obj2。t1锁定obj1、t2锁定obj2。同时t1需要obj2才能执行,而obj2被t2锁定,不能获取。同理,t2也不能获取t1锁定的obj1,不能完成操作。
Java代码 
public class DeadLockSample implements Runnable {   
    public int flag = 1;   
    static Object o1 = new Object(), o2 = new Object();   
    public void run() {   
                     System.out.println("flag=" + flag);   
        if(flag == 1) {   
            synchronized(o1) {   
                try {   
                    Thread.sleep(500);   
                } catch (Exception e) {   
                    e.printStackTrace();   
                }   
                synchronized(o2) {   
                    System.out.println("1");       
                }   
            }   
        }   
        if(flag == 0) {   
            synchronized(o2) {   
                try {   
                    Thread.sleep(500);   
                } catch (Exception e) {   
                    e.printStackTrace();   
                }   
                synchronized(o1) {   
                    System.out.println("0");   
                }   
            }   
        }   
    }      
    
    public static void main(String[] args) {   
        TestDeadLock td1 = new TestDeadLock();   
        TestDeadLock td2 = new TestDeadLock();   
        td1.flag = 1;   
        td2.flag = 0;   
        Thread t1 = new Thread(td1);   
        Thread t2 = new Thread(td2);   
        t1.start();   
        t2.start();   
    }   
}  

t1锁定o1后休眠,t2锁定o2后休眠。然后t1去锁定o2,不能锁定,等待o2释放。然而o2要等t2执行完毕后才能释放,而t2在等待t1锁定的o1,这样就形成了t1和t2的循环等待。发生死锁现象。其中,休眠只是让每次结果都出现死锁现象,而不用休眠的情况也可能发生死锁现象。
此外,还有多个线程的循环等待问题(5个哲学家吃饭问题)。
二、死锁解决方法
1、死锁预防:加大锁定的粒度,如上面的例子中使得进程锁定当前对象,而不是逐步锁定当前对象的两个子对象o1和o2。这样就在t1锁定o1之后,即使发生休眠,当前对象仍然被t1锁定,t2不能打断t1,锁定o2,等t1休眠后再锁定o2,获取资源,执行成功。然后释放当前对象,t2运行。

你可能感兴趣的:(java线程)