我正在尝试使用多线程来模拟一个简单的恒温器。恒温器应提高温度,以达到用户要求的值,即下面代码中的"Max“值。我有两个线程,一个负责增加温度,另一个负责降低温度。但减少的条件是它应该只在燃气关闭的情况下运行。但我在实现这个概念时遇到了一个问题。每次我按下向上按钮以增加所需的温度时,GUI就会冻结。我该如何解决这个问题?
这就像一个线程持有锁,不会释放它,但是我怎么能注意到是哪一个呢?
`private volatile boolean isBoilerOn = false;
protected int Max, Current;
protected boolean isDone, isGasOn, isPumpOn;
private temperatureUp tempUp;
private temperatureDown tempDown;
public void setBoilerSatus(boolean status) {
this.isBoilerOn = status;
}
public boolean getBoilerStatus() {
return this.isBoilerOn;
}
private synchronized void setGasBoilerStatus() {
if(Max>Current)
setBoilerSatus(true);
else
setBoilerSatus(false);
notifyAll();
}
private void btnUpActionPerformed(java.awt.event.ActionEvent evt) {
if(Max<=8)
{
Max++;
String strI = String.valueOf(Max);
lblDesiredTemp.setText(strI);
setGasBoilerStatus();
}
}
private void btnDownActionPerformed(java.awt.event.ActionEvent evt) {
if(Max>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
{
while (!getBoilerStatus())
wait();
if(Max>Current)
{
Thread.sleep(4000);
Current ++;
}
setGasBoilerStatus();
}
private synchronized void decreaseTemeture() throws InterruptedException
{
while(getBoilerStatus()) wait();
Thread.sleep(4000);
if(Current == 0 )
return;
Current --;
setGasBoilerStatus();
}
private void systemInitial()
{
isGasOn = false;
Max = Current = 0;
}
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());
}
}
}
};`发布于 2012-07-25 20:12:27
invokeLater()来启动/管理/停止Background task setGasBoilerStatus(); ???,您会遇到Concurency in SwingSwingWorker没有被指定为重复运行长任务的问题,如果您的任务很简单,并且您只想运行此任务一次(从单击Event Dispatch Thread,这是使用d16所必需的,但仅用于Swing JComponents的更新,例如,代码行d17应该包装到d18中,setText()被声明为Thread Safe我看到了很多不正确的问题txtLog.setText(w + "\n" + txtLog.getText());是关于使用JTextArea而不是append()的情况下更好地帮助发布<代码>C31演示的问题,可能还有另一个问题<代码>H232<代码>F233发布于 2012-07-25 19:52:11
发生这种情况是因为您没有正确使用invokeLater。看看这里:Java AWT Threads
https://stackoverflow.com/questions/11648907
复制相似问题