Note that there are some explanatory texts on larger screens.

plurals
  1. POThread Wait and Wake up
    text
    copied!<p>I'm trying to simulate a simple thermostat, using multi-threading. The thermostat should increase the temperature in order to reach the value that the user requested for which is "Max" value in the code below. I have two thread, one in charge of increasing the temperature and the other for decreasing it. but the condition for decreasing is it should be only running when the gas is off. but I have a problem with implementing this concept. as the code below runs, the second thread keeps throwing exception of null!</p> <pre><code>&lt;pre&gt;&lt;code&gt;`private void formWindowActivated(java.awt.event.WindowEvent evt) { systemInitial(); Thread temperatureUp = new Thread() { @Override public void run() { while(true) { Max = Integer.parseInt(lblDesiredTemp.getText()); Current = Integer.parseInt(lblCurrentTemp.getText()); try { if(Max&gt;Current) { lblGasStatus.setText("On"); lblTemperatureSensor.setText("increasing"); increaseTemeture(); } else { lblGasStatus.setText("Off"); if(Current != 0) lblTemperatureSensor.setText("decreasing"); else lblTemperatureSensor.setText("----"); } } catch(Exception ex) { txtLog.setText(ex.getMessage() + "\n" + txtLog.getText() ); } } } }; Thread systemUpdater = new Thread() { @Override public void run() { while(true) { try { notifyGasBoiler(this); if(Current&gt;0) decreaseTemeture(); } catch(Exception ex) { txtLog.setText(ex.getMessage() + "\n" + txtLog.getText() ); } } } }; temperatureUp.start(); systemUpdater.start(); } private synchronized void notifyGasBoiler(Thread gasOff) throws InterruptedException { try { if("On".equals(lblGasStatus.getText())) { gasOff.wait(); txtLog.setText(txtLog.getText() + "\n" + gasOff.getName() + " waits."); } else notifyAll(); } catch (Exception ex) { txtLog.setText(ex.getMessage() + "\n" + txtLog.getText() ); } }` </code></pre> <p></p> <p>what am I missing here?</p> <p>UPDATE I:</p> <p>this is the log I'm getting by running the system and request the 2 temperature:</p> <p>Temperature increased to 1 Temperature increased to 2 null null null ....</p> <p>UPDATE II:</p> <p>I used printStackTrace for exception and it got me this:</p> <p><code>java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at sol.smarthome.GUI.notifyGasBoiler(GUI.java:300) at sol.smarthome.GUI.access$900(GUI.java:14) at sol.smarthome.GUI$5.run(GUI.java:276)</code></p> <hr> <p>Update III</p> <pre><code>&lt;pre&gt;&lt;code&gt;`private void btnUpActionPerformed(java.awt.event.ActionEvent evt) { if(Max&lt;=8) { Max++; String strI = String.valueOf(Max); lblDesiredTemp.setText(strI); setGasBoilerStatus(); } } private void btnDownActionPerformed(java.awt.event.ActionEvent evt) { if(Max&gt;0) { Max--; String strI = String.valueOf(Max); lblDesiredTemp.setText(strI); setGasBoilerStatus(); } } private void formWindowActivated(java.awt.event.WindowEvent evt) { systemInitial(); tempUp = new temperatureUp(); tempDown = new temperatureDown(); tempUp.start(); tempDown.start(); } private synchronized void increaseTemeture() throws InterruptedException { synchronized (monitor) { if (!getBoilerStatus()) { tempUp.wait(); //return; } else { Max = Integer.parseInt(lblDesiredTemp.getText()); Current = Integer.parseInt(lblCurrentTemp.getText()); if(Max&gt;Current) { lblGasStatus.setText("On"); lblTemperatureSensor.setText("increasing"); Thread.sleep(4000); Current ++; lblPumpStatus.setText("On"); lblCurrentTemp.setText(String.valueOf(Current)); txtLog.setText("Temperature increased to " + Current + "\n"+ txtLog.getText()); if(Current&gt;8) lblDanger.setVisible(true); } setGasBoilerStatus(); if(!isGasOn) { try { Thread.sleep(1000); } catch (InterruptedException ex) { //Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } lblGasStatus.setText("Off"); if(Current != 0) lblTemperatureSensor.setText("decreasing"); else lblTemperatureSensor.setText("----"); } } } } private synchronized void decreaseTemeture() throws InterruptedException { synchronized (monitor) { if(getBoilerStatus()) { tempDown.wait(); //return; } else { Thread.sleep(4000); if(Current == 0 ) return; Current --; lblCurrentTemp.setText(String.valueOf(Current)); lblDanger.setVisible(false); txtLog.setText("Temperature decreased to " + Current + "\n"+ txtLog.getText()); if(Current&lt;1) lblPumpStatus.setText("Off"); else lblPumpStatus.setText("On"); setGasBoilerStatus(); } } } private void systemInitial() { lblDanger.setVisible(false); isPilotOn.setSelected(true); lblGasStatus.setText("Off"); lblPumpStatus.setText("Off"); isDone = true; isGasOn = false; Max = Current = 0; } // indicates if the boiler is on (true) or off (false) // set as volatile to stop caching private volatile boolean isBoilerOn = false; protected int Max, Current; protected boolean isDone, isGasOn, isPumpOn; private temperatureUp tempUp; private temperatureDown tempDown; // Used to synchronize thread access to internal state (Current and // isBoilerOn member variables. The monitor is private in order // for this class to encapsulate its synchronization policy. private final Object monitor = new Object(); // update the bolier's status to on (true) or off (false) public void setBoilerSatus(boolean status) { synchronized (monitor) { // block threads until boiler is switched on this.isBoilerOn = status; // (see below), this is the place to notify them... notifyAll(); } } // returns true if the boiler is on, false otherwise public synchronized boolean getBoilerStatus() { synchronized (monitor) { return this.isBoilerOn; } } private void setGasBoilerStatus() { synchronized (monitor) { if(Max&gt;Current) setBoilerSatus(true); else setBoilerSatus(false); } } class temperatureUp extends Thread { @Override public void run() { while(true) { try { increaseTemeture(); } catch(Exception ex) { StringWriter w = new StringWriter(); ex.printStackTrace(new PrintWriter(w)); //txtLog.setText(w + "\n" + txtLog.getText()); } } } }; class temperatureDown extends Thread { @Override public void run() { while(true) { try { decreaseTemeture(); } catch(Exception ex) { StringWriter w = new StringWriter(); ex.printStackTrace(new PrintWriter(w)); //txtLog.setText(w + "\n" + txtLog.getText()); } } } }; ` </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload