此文章转自:http://blog.csdn.net/wlbing0625/article/details/7899565
一、什么是死锁?
摘自百度: 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁. 关键点:1)两个以上的进程 2)争夺共享的资源 3)它们各自不释放手中资源,除非有外力协助 二、死锁例子: public class TestDealLock implements Runnable{ /** * @param args */ public static void main(String[] args) { TestDealLock lock1=new TestDealLock(); TestDealLock lock2=new TestDealLock(); Thread thread1=new Thread(lock1); Thread thread2=new Thread(lock2); lock1.setFlag(0); lock2.setFlag(1); thread1.start(); thread2.start(); } private static Object obj1=new Object();//一把A筷子的锁 private static Object obj2=new Object();//一把B筷子的锁 private int flag=0; public int getFlag() { return flag; } public void setFlag(int flag) { this.flag = flag; } public void eatMeat(){ synchronized (obj1) { System.out.println(Thread.currentThread().getName()+":拿到A筷子!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj2) { System.out.println(Thread.currentThread().getName()+":拿到B筷子!开始吃饭"); } } } public void eatVegetable(){ synchronized (obj2) { System.out.println(Thread.currentThread().getName()+":拿到B筷子!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj1) { System.out.println(Thread.currentThread().getName()+":拿到A筷子!开始吃饭"); } } } @Override public void run() { if(flag==0){ eatMeat(); }else{ eatVegetable(); } } } 三、解决办法: 1)、让所有的线程按照同样的顺序获得一组锁。这种方法消除了 X 和 Y 的拥有者分别等待对方的资源的问题。 2)、将多个锁组成一组并放到同一个锁下。前面Java线程死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。 3)、将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。(没有实现) 实现1: @Override public void run() { /* if(flag==0){ eatMeat(); }else{ eatVegetable(); }*/ eatMeat(); } 实现2、 /** * 然要探测或推敲各种情况是非常困难的,但只要按照下面几条规则去设计系统,就能够避免Java线程死锁问题: 一、让所有的线程按照同样的顺序获得一组锁。这种方法消除了 X 和 Y 的拥有者分别等待对方的资源的问题。 二、将多个锁组成一组并放到同一个锁下。前面Java线程死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。 三、将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。(没有实现) * @author abc * */ public class TestDealLock implements Runnable{ /** * @param args */ public static void main(String[] args) { TestDealLock lock1=new TestDealLock(); TestDealLock lock2=new TestDealLock(); Thread thread1=new Thread(lock1); Thread thread2=new Thread(lock2); lock1.setFlag(0); lock2.setFlag(1); thread1.start(); thread2.start(); } private static Object obj1=new Object();//一把A筷子的锁 private static Object obj2=new Object();//一把B筷子的锁 private static Object obj3=new Object();//加一把锁,保证A锁和B锁锁上同一组,只有拿到此锁才能拿到A锁或者B锁 private int flag=0; public int getFlag() { return flag; } public void setFlag(int flag) { this.flag = flag; } public void eatMeat(){ synchronized (obj3) { synchronized (obj1) { System.out.println(Thread.currentThread().getName()+":拿到A筷子!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj2) { System.out.println(Thread.currentThread().getName()+":拿到B筷子!开始吃饭"); } } } } public void eatVegetable(){ synchronized (obj3) { synchronized (obj2) { System.out.println(Thread.currentThread().getName()+":拿到B筷子!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj1) { System.out.println(Thread.currentThread().getName()+":拿到A筷子!开始吃饭"); } } // } } } @Override public void run() { if(flag==0){ eatMeat(); }else{ eatVegetable(); } } } 第三种方法不知道怎么实现,求指教。。。。