第二十八篇:JAVA多线程机制之死锁

来源:互联网 发布:hisuite mac版 编辑:程序博客网 时间:2024/05/16 15:29

同步特性使用起来非常方便,功能很强大。但有的时候考虑不周的话有可能出现线程死锁。死锁主要是多个线程争抢资源造成的。 
下面通过一个例子演示死锁:

class Resource{   private int res = 0;   public int getRes()   {      return res;   }   public void setRes(int res)   {      this.res = res;   }}class DeadLock1 extends Thread{   Resource res1 = null;   Resource res2 = null;   public DeadLock1(String name, Resource res1, Resource res2)   {      super(name);      this.res1 = res1;      this.res2 = res2;   }   @Override   public void run()   {      // 获取res1的锁从而锁住res1      synchronized (res1)      {         for (int i = 0; i < 10; i++)         {            int r = res1.getRes();            r++;            res1.setRes(r);         }         System.out.println(getName() + ":资源1处理完毕等待资源2...");         try         {            Thread.sleep(1000);         }         catch (InterruptedException e)         {            System.out.println(getName() + "异常中断");         }         // 此时res1并未释放         // 获取res2的锁从而锁住res2         synchronized (res2)         {            for (int i = 0; i < 10; i++)            {               int r = res2.getRes();               r++;               res2.setRes(r);            }            System.out.println(getName() + ":资源2处理完毕...");         }      }   }}class DeadLock2 extends Thread{   Resource res1 = null;   Resource res2 = null;   public DeadLock2(String name, Resource res1, Resource res2)   {      super(name);      this.res1 = res1;      this.res2 = res2;   }   @Override   public void run()   {      // 获取res1的锁从而锁住res2      synchronized (res2)      {         for (int i = 0; i < 10; i++)         {            int r = res2.getRes();            r++;            res2.setRes(r);         }         System.out.println(getName() + ":资源2处理完毕等待资源1...");         try         {            Thread.sleep(1000);         }         catch (InterruptedException e)         {            System.out.println(getName() + "异常中断");         }         // 此时res2并未释放         // 获取res1的锁从而锁住res1         synchronized (res1)         {            for (int i = 0; i < 10; i++)            {               int r = res1.getRes();               r++;               res1.setRes(r);            }            System.out.println(getName() + ":资源1处理完毕...");         }      }   }}public class DeadLockDemo{   public static void main(String[] args)   {      // 新建共享资源      Resource res1 = new Resource();      Resource res2 = new Resource();      DeadLock1 lock1 = new DeadLock1("线程1", res1, res2);      DeadLock2 lock2 = new DeadLock2("线程2", res1, res2);      lock1.start();      lock2.start();   }}

运行结果: 
线程1:资源1处理完毕等待资源2… 
线程2:资源2处理完毕等待资源1…

程序说明:线程1和线程2共享资源res1和res2,当线程1首先运行获取资源res1的锁从而锁住res1,调用sleep()使线程2得以运行,此时资源res1还未释放。线程2锁住资源res2,调用sleep(),线程1运行,此时资源res2还未释放,线程1尝试获取资源res2但是已经被线程2锁住,线程2睡眠过后开始运行尝试获取资源res1的锁但是已经被线程1锁住。此时线程1和线程2处于死锁状态。