JAVA多线程机制之死锁

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

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处于死锁状态。

你可能感兴趣的:(java,多线程,线程,死锁)