notify notifyAll 和死锁

20140217 问题解决: 参考 

第21章 - 并发 - 单一生产者与消费者,多个生产者与多个消费者(P709) 

http://jackyin5918.iteye.com/blog/2018319

 

主要原因是因为使用单一锁,单一条件,使用Lock 创建两个Condition 根据不同条件调用不同condition.的signalAll()方法.

 

下面这个代码参考:http://www.cnblogs.com/Gordon-YangYiBao/archive/2012/09/16/2687520.html

原文说用notifyAll替代notify可解决死锁,其实不行,还是死锁,解决方法还未实现

 

package com.app.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 
 * 辅助类OutTurn的一个方法输出基数,一个方法输出偶数,两个方法均有通过同步交替输出.
 * 同步条件isOdd==true是输出基数,isOdd==false输出偶数
 * 主类LockDemo,中实现两个runnable,OddPrinter和EvenPrinter分别输出基数和偶数
 * 
 */
public class LockDemo
{
  private static final OutTurn ot = new OutTurn();

  public static void main(String[] args)
  {
    // System.out.println("lock");
    ExecutorService service = Executors.newCachedThreadPool();
    for (int j = 0; j < 10000; j++) //这里要循环次数大一些的,否则不容易出现死锁
    {
      service.submit(new OddPrinter());
      service.submit(new EvenPrinter());
    }
    service.shutdown();
  }
  
  /**
   * printEven (((((((((((( 5202
     printOdd ---- 5203
     printEven (((((((((((( 5204
     printOdd ---- 5205
     printEven (((((((((((( 5206
   * 运行到上面时卡住了,表示死锁了.
   * 分析: 上面是输出5026后死锁的,此时isOdd=true,然后调用notify方法,此方法
   * 唤醒一个线程(其他线程都处于等待状态),假如唤醒的线程还是EvenPrinter,则此线程会立即
   * 执行
   * while (isOdd)
      {
        this.wait();
      }
      此时,这个唯一的唤醒的线程也处于等待状态,然后 所有线程都处于等待状态了,然后导致死锁.
      
      将所有的notify方法换成notifyAll方法 还是不行
   *
   */

  static class OddPrinter implements Runnable
  {
    @Override
    public void run()
    {
      ot.printOdd();
    }
    
  }

  static class EvenPrinter implements Runnable
  {
    @Override
    public void run()
    {
      ot.printEven();
    }
  }
}

class OutTurn
{
  private boolean isOdd = true;
  private int     count = 1;

  public synchronized void printOdd()
  {
    try
    {
      while (!isOdd)
      {
        this.wait();
      }
      System.out.println("printOdd ---- " + count);
      isOdd = false;
      this.notifyAll();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    count++;

  }

  public synchronized void printEven()
  {
    try
    {
      while (isOdd)
      {
        this.wait();
      }
      System.out.println("printEven (((((((((((( " + count);
      isOdd = true;
      this.notifyAll();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    count++;
  }

}

 

你可能感兴趣的:(notifyAll)