栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

notify导致死锁的示例

notify导致死锁的示例

      在多线程之间的同步中,一般采用Object.wait()、Object.notify()、Object.notifyAll()来实现,而notify可能会导致多线程之间出现死锁,下面通过生产者消费者的示例来说明:

      生产者代码:

while(true) {
  synchronized (queue) {
     while (queue.size() == maxSize) { #ref_p1
       try {
          System.out.println("已满");
          queue.wait();  #ref_p2
          System.out.println("已唤醒生产者---");
          } catch (InterruptedException e) {
            System.out.println("生产者报错");
          }
     }
     Random random = new Random();
     int i = random.nextInt();
     System.out.println("Produce " + i);
     queue.add(i);
     queue.notify();
  }
}

       消费者代码:

while(true) {
  synchronized (queue) {
    while (queue.isEmpty()) {
      try {
        System.out.println("已空");
        queue.wait();   #ref_c1
        System.out.println("已唤醒消费者---");
      } catch (InterruptedException e) {
         System.out.println("消费者报错");
      }
    }
    int v = queue.remove();
    System.out.println("Consume " + v);
    queue.notify();
  }
}

        队列queue的最大长度设为1,假设有2个生产者线程P1、P2,2个消费者线程C1、C2,黄色表示线程调用wait阻塞,红色表示线程获取锁阻塞。

       1. C1和C2首先执行,由于初始队列为空,故阻塞在#ref_c1处,此时4个线程状态如下: 

       2. P1获取到锁执行,往队列中插入数据,并调用notify释放锁,假设此时C1被唤醒,P2获取到锁,则P1在下一次循环中获取锁阻塞

       3. 假设P2获取到锁开始执行到#ref_p1处时,C1还没有从队列中获取数据,则此时队列已满,P2在#ref_p2处阻塞(同时释放queue上的锁)

       4. C1继续执行,从队列中移除数据,并调用notify,假设该notify唤醒了C2,C2继续执行,由于此时队列已空,故C2在内循环中仍然阻塞在#ref_c1处

       5. C1在下一循环中获取到queue上的锁,继续执行,由于此时队列为空,故和C2一样,阻塞在#ref_c1处(同时释放queue上的锁)

       6. P1获取到queue上的锁,开始执行,由于此时队列为空,故P1往队列中插入一条数据,并调用notify,假设该notify唤醒了线程P2,P2从#ref_p2处继续开始执行,由于此时队列中有一条数据,即队列已满,故P2在内循环中仍然阻塞在#ref_p2处

       7. P1在下一循环中执行到#ref_p1处,由于此时队列已满,故阻塞在#ref_p2处

      到此时,4个线程都处于阻塞状态,任何一个都无法被唤醒,即发生了死锁

       从示例中可见,notify导致死锁的原因时只能唤醒一个处于阻塞状态的线程,而解决死锁的方法也很简单,在第6步中如果调用了notifyAll,则会唤醒消费者线程,C1和C2被唤醒之后获取队列中的数据,使得流程可以继续进行下去,从而避免了死锁的发生

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/612566.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号