package threads;

/**
 *  NOTE: This implementation of the SteamBoiler class is implemented
 *  with regard to synchronization.  
 */
public class SteamBoiler
{
  public static final int PRESSURE_LIMIT = 20;
  public static final int BURNER_COUNT = 10;
  
  public Burner[] start()
  {
    Burner[] burners = new Burner[BURNER_COUNT];
    for (int burner = 0; burner < BURNER_COUNT; burner++)
    {
      burners[burner] = new Burner(this);
      burners[burner].start();
    }
    
    return burners;
  }
  
  public int getPressure()
  {
    return m_pressure;
  }
  
  public void setPressure(int pressure)
  {
    m_pressure = pressure;
  }
  
  public static void main(String[] args)
  {
    SteamBoiler boiler = new SteamBoiler();
    
    Burner[] burners = boiler.start();
    
    for (int burner = 0; burner < BURNER_COUNT; burner++)
    {
      try
      {
        burners[burner].join();     // Wait for thread to finish
      }
      catch (InterruptedException e)
      {
        // This thread was interrupted.
      }
    }
    
    System.out.println("Pressure reads " + boiler.getPressure() +
      ", limit is " + PRESSURE_LIMIT);
  }
  
  /////// Data //////
  private int m_pressure = 0;
}

class Burner extends Thread
{
  public static final int PRESSURE_INCREMENT = 15;
  
  public Burner(SteamBoiler boiler)
  {
    m_boiler = boiler;
  }
  
  public void run()
  {
    burn();
  }
  
  private void burn()
  {
    synchronized (m_boiler)
    {
      if (m_boiler.getPressure() <
        SteamBoiler.PRESSURE_LIMIT - PRESSURE_INCREMENT)
      {
        // Wait to simulate delay
        try
        {
          sleep(100);
        }
        catch (InterruptedException e)
        {
          // Ignore
        }
        
        m_boiler.setPressure( m_boiler.getPressure() +
          PRESSURE_INCREMENT );
      }
    }
  }
  
  ///// Private data //////
  private SteamBoiler m_boiler;
}