gpt4 book ai didi

java - InvokeLater 卡住 GUI

转载 作者:行者123 更新时间:2023-12-01 15:15:37 25 4
gpt4 key购买 nike

我正在尝试使用多线程模拟一个简单的恒温器。恒温器应提高温度以达到用户请求的值,即下面代码中的“最大值”。我有两个线程,一个负责提高温度,另一个负责降低温度。但减少的条件是必须在关气时才运行。但我在实现这个概念时遇到了问题。每次我按下向上按钮以增加所需的温度时,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());
}
}
}
};`

最佳答案

  • 不要使用invokeLater()来启动/管理/停止后台任务 setGasBoilerStatus(); ???,您对 Swing 中的并发

  • 存在问题
  • SwingWorker 未指定重复运行长任务,请使用 Runnable#Thread 代替

  • 如果您的任务很简单,并且您只想运行一次此任务(通过 JButtons 单击),则可以使用 SwingWorker

  • 基本上可以从代码中调用事件调度线程,需要使用invokeLater(),但仅用于更新 Swing JComponent,例如代码行 txtLog.setText(w + "\n"+ txtLog.getText()); 应包装在 invokeLater() 中,

  • 自从 setText() 被声明为线程安全以来,我看到了很多问题,但事实并非如此

  • 如果 txtLog.setText(w + "\n"+ txtLog.getText()); 是关于 JTextArea 使用 append() 而不是 setText(whatever + getText())

  • 为了获得更好的帮助,请尽快发布 SSCCE已证实存在问题,也许还有另一个问题

关于java - InvokeLater 卡住 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11648907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com