首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >InvokeLater冻结图形用户界面

InvokeLater冻结图形用户界面
EN

Stack Overflow用户
提问于 2012-07-25 19:41:04
回答 2查看 574关注 0票数 0

我正在尝试使用多线程来模拟一个简单的恒温器。恒温器应提高温度,以达到用户要求的值,即下面代码中的"Max“值。我有两个线程,一个负责增加温度,另一个负责降低温度。但减少的条件是它应该只在燃气关闭的情况下运行。但我在实现这个概念时遇到了一个问题。每次我按下向上按钮以增加所需的温度时,GUI就会冻结。我该如何解决这个问题?

这就像一个线程持有锁,不会释放它,但是我怎么能注意到是哪一个呢?

代码语言:javascript
复制
`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());
        }
    }
}
};`
EN

回答 2

Stack Overflow用户

发布于 2012-07-25 20:12:27

  • 不要使用invokeLater()来启动/管理/停止Background task setGasBoilerStatus(); ???,您会遇到Concurency in Swing
  • SwingWorker没有被指定为重复运行长任务的问题,如果您的任务很简单,并且您只想运行此任务一次(从单击
  • ),那么可以从您的代码中调用Event Dispatch Thread,这是使用d16所必需的,但仅用于Swing JComponents的更新,例如,代码行d17应该包装到d18中,
  • 由于setText()被声明为Thread Safe我看到了很多不正确的问题
  • txtLog.setText(w + "\n" + txtLog.getText());是关于使用JTextArea而不是append()的情况下更好地帮助发布<代码>C31演示的问题,可能还有另一个问题<代码>H232<代码>F233
票数 1
EN

Stack Overflow用户

发布于 2012-07-25 19:52:11

发生这种情况是因为您没有正确使用invokeLater。看看这里:Java AWT Threads

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11648907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档