0

マルチスレッドを使用して、単純なサーモスタットをシミュレートしようとしています。サーモスタットは、ユーザーが要求した値 (以下のコードの「最大」値) に到達するために温度を上げる必要があります。私は2つのスレッドを持っています.1つは温度を上げることを担当し、もう1つは温度を下げることを担当しています。減る条件はガス抜き時のみ。しかし、この概念の実装には問題があります。希望の温度を上げるために上ボタンを押すたびに、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());
        }
    }
}
};`
4

2 に答える 2

1
  • invokeLater()の開始/管理/停止には使用しないBackground task setGasBoilerStatus(); ???でください。問題があります。Concurency in Swing

  • SwingWorker長いタスクを繰り返し実行するように指定されていない場合は、Runnable#Thread代わりに使用してください

  • タスクが単純で、このタックを1回だけ実行したい場合(JButtonsクリックから)、次に使用しますSwingWorker

  • Event Dispatch Thread基本的には、コードから呼び出すことができます。使用する必要がありますinvokeLater()が、Swing JComponentsの更新の場合のみです。たとえば、コード行txtLog.setText(w + "\n" + txtLog.getText());は、にラップする必要がありますinvokeLater()

  • setText()私が見たように宣言されているのでThread Safe、それが真実ではない多くの質問があります

  • の代わりに使用txtLog.setText(w + "\n" + txtLog.getText());しようとしている場合JTextAreaappend()setText(whatever + getText())

  • SSCCEで実証された問題をより早く投稿するためのより良いヘルプのために、mabyeには別の問題があります/あります

于 2012-07-25T12:12:27.090 に答える
0

これは、invokeLaterを正しく使用していないために発生しています。ここを見てください:JavaAWTスレッド

于 2012-07-25T11:52:10.750 に答える