I've been told that using Thread.Sleep()
is a bad solution at times that one would want to make some time interval within a loop of actions in a synchronized method.
On the other hand, I have two different threads which are active throughout the running time of my program and also one shared object and when I use Object.wait(long) in that shared object, it causes my GUI to freeze for some time.
what would be a better solution for this problem?
Update This portion of the code is including one of the threads which is starting in GUI:
class temperatureUp extends Thread
{
@Override
public void run()
{
while(true)
{
try
{
GBC.increaseTemp();
updateSystemStatus();
}
catch(Exception ex)
{
StringWriter w = new StringWriter();
ex.printStackTrace(new PrintWriter(w));
txtLog.setText(w + "\n" + txtLog.getText());
}
}
}
};
and this is the synchronized method in shared object, GBC:
public synchronized void increaseTemp() throws InterruptedException{
// don't increase the temperature if the boiler
// is not turned on...
while (!isBoilerOn)
wait();
// increase the current temperature
if ((currentTemp + 1) < MAX_TEMP && currentTemp < desiredTemp) {
Thread.sleep(2000); ///what should put here if not thread sleep?
currentTemp ++;
updateGasBoilerStatus();
}
}
Don't sleep inside the synchronized method! Don't wait in GUI event handlers/methods!
Split up the sychronized actions so that the Sleep() call is not called in the GUI thread context.
Maybe use use InvokeLater() for the second bit.
You could shrink the scope of the synchronize
statement. For instance if you are synchronizing on the whole method
public synchronized void foo()
You could remove the modifier and use a synchronized block instead
synchronized (this) {
// ...
}
and move the Thread.sleep()
outside of this block if possible. Only synchronize on those statements which modify states of shared data.
A lot of threading problems regarding Swing are related to the Event Dispatcher Thread and can be easily solved with it. I recommend you read into it.
A little bit background, why you shouldn't call Thread.sleep()
inside a synchronization block:
Sleeping or waiting while holding a lock. Calling Thread.sleep with a lock held can prevent other threads from making progress for a long time and is therefore a potentially serious liveness hazard. Calling Object.wait or Condition.await with two locks held poses a similar hazard. [JCIP]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With