死锁的概念

“死锁”指的是:

多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。

          

因此, 某一个同步块需要同时拥有两个以上对象的锁时,就可能会发生死锁的问题。下面案例中,“化妆线程”需要同时拥有镜子对象口红对象才能运行同步块。那么,实际运行时,小丫的化妆线程拥有了镜子对象,大丫的化妆线程拥有了口红对象,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的死锁状态 

【示例1】死锁示例

class Lipstick{

   

}

class Mirror{

   

}

 

class Makeup extends Thread {

    int flag;

    String girl;

    static Lipstick lipstick=new Lipstick();

    static Mirror mirror= new Mirror();

   

    @Override

    public void run() {

       // TODO Auto-generated method stub

       doMakeup();

    }

    void doMakeup(){

       if(flag==0){

           synchronized (lipstick) {

              System.out.println(girl+"拿着口红!");

              try {

                  Thread.sleep(1000);

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

             

              synchronized (mirror) {

                  System.out.println(girl+"拿着镜子!");

              }

             

           }

       }

       else{

           synchronized (mirror) {

              System.out.println(girl+"拿着镜子!");

              try {

                  Thread.sleep(2000);

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

              synchronized (lipstick) {

                  System.out.println(girl+"拿着口红!");

              }

           }

       }

    }

   

}

 

public class TestDeadLock {

    public static void main(String[] args) {

       Makeup m1 = new Makeup();  m1.girl="大丫"; m1.flag=0;

       Makeup m2 = new Makeup();  m2.girl="小丫"; m2.flag=1;

       m1.start();

       m2.start();

    }

}

  图1 线程互相等待“资源”而处于“停滞”状态

死锁的解决方法

死锁是由于同步块需要同时持有多个对象锁造成的,要解决这个问题,思路很简单,就是:

同一个代码块,不要同时持有两个对象锁。 

如上面的死锁案例,修改成示例2所示。

 【示例2】死锁问题的解决(修改示例1doMakeup方法)

    void doMakeup(){

       if(flag==0){

           synchronized (lipstick) {

              System.out.println(girl+"拿着口红!");

              try {

                  Thread.sleep(1000);

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

             

             

           }

           synchronized (mirror) {

              System.out.println(girl+"拿着镜子!");

           }

       }

       else{

           synchronized (mirror) {

              System.out.println(girl+"拿着镜子!");

              try {

                  Thread.sleep(2000);

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

           }

           synchronized (lipstick) {

              System.out.println(girl+"拿着口红!");

           }

       }

    }








「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。


 笔记包含从浅入深的六大部分:

 A-Java入门阶段

 B-数据库从入门到精通

 C-手刃移动前端和Web前端

 D-J2EE从了解到实战

 E-Java高级框架精解

 F-Linux和Hadoop