8

編集 この投稿は、学校の宿題に関連しており、swing に依存してスレッドとブロック用のブール値フラグを表示するように指示されています。

私のアプリケーションは、それぞれがスレッドを含む一連の「ジョブ」オブジェクトを作成します。各ジョブはクリーチャーに属します。クリーチャーは複数の仕事を持つことができますが、一度に実行できるのはそのうちの 1 つだけです。

私のスレッドは、「killFlag」と「goFlag」という 2 つのブール値フラグを使用して、実行する必要があるかどうかを示します。それは、それが属するクリーチャーを「対象」として指定します。また、各ターゲットにはブール値の「isWorking」があり、別のジョブでビジーかどうかを示します。

これは、各ジョブが実行するスレッドです。

public void run() {
    long time = System.currentTimeMillis();
    long startTime = time;
    long stopTime = time + 1000 *  (long)( jobTime );
    double duration = stopTime - time;



    synchronized (this.target) {
        while (this.target.isWorking) {
            status = 'w';
            showStatus(); // hmmmmmmmm
            try {
                this.target.wait();
            } catch (InterruptedException e) {
            }
        }

        this.target.isWorking = true;
    }

    while (time < stopTime && !killFlag) {
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
        }

        if (goFlag) {
            status = 'p';
            showStatus();
            time += 100;
            this.showProgress.setValue((int)(((time - startTime) / duration) * 100));
        } else {
            status = 'r';
            showStatus();
        }
    }//End While loop here

        showProgress.setValue(100);
        status = 'c';
        showStatus();
        synchronized (target) {
            target.isWorking = false;
            target.notifyAll();

    }
}

target.notifyAll()最初はそれがスローされているためだと思いましたがIllegalMonitorStateException、コメントアウトするとスレッドはオブジェクトを構築しますが、GUI でそれらを表示すると、それらの 80% は私と他の 20% からの相互作用なしで完全に表示されます。生き物が忙しいと言っています。

最初は、これはキル フラグを立てるのが早すぎるためだと思っていましたが、それを下に移動したり削除したりしても、まだ症状が持続します。私は現在配備されており、ここにはプログラマーがいません。ははは、あなたが提供できるアドバイスは世界を意味します。

以下に十分な情報を提供することを確認するために、スレッドと対話するために使用する方法を示します。以下のメソッドは、スレッドが実行されているかどうかに基づいて変化するボタンで動作します。

public void showStatus() { //switch that changes status of button used to start / pause / display status of thread
    switch (this.status) {
        case 'r' :
            startJob.setEnabled(true);
            startJob.setText ("Run");
            break;
        case 'p' :
            startJob.setEnabled(true);
            startJob.setText("Pause");
            break;
        case 'w' :
            startJob.setEnabled(false);
            startJob.setText("Working");
            break;
        case 'c' :
            startJob.setEnabled(false);
            startJob.setText("Job Complete");
            break;
    }
}

private class theHandler implements ActionListener {//Listener for Button mentioned above
    public void actionPerformed (ActionEvent event) {
        if (event.getSource() == startJob) {
            if (goFlag) {
                goFlag = false;
            } else {
                goFlag = true;
                killFlag = false;
            }
        } else if (event.getSource() == stopJob) {
            if (killFlag) {
                //do nothing
            } else {
                killFlag = true;
                status = 'r';
            }
        }
    }
}

これは私を殺しています。私はこれを解決するために6時間掘り下げてきました。

編集

MadProgrammer のコメントに基づいてコードを調整した後、「target.notifyAll()」が修正されました。ここでの問題は、ボタンが状態間で一瞬ランダムに点滅しても、すべてのスレッドが完了したようにディスプレイに表示されるようです。

編集

コメントに応じて以下に含まれる多くの編集

以下は、killFlag、goFlag などが定義されているジョブ クラスを定義する方法です。

  class Job extends Item implements SearchableByName, Runnable {
int                                         index;
String                                      name;
int                                         creature;
double                                      jobTime;
Creature                                    target;
boolean                                     goFlag = false;
boolean                                     killFlag = false;
char                                        status;
JButton                                     startJob;
JButton                                     stopJob;
JProgressBar                                showProgress;
JPanel                                      p1;

以下は、ブーリアン isWorking が存在するクリーチャー (ターゲット) が定義されている場所です。

 class Creature extends Entity implements SearchableByName, SearchableByType, Runnable {
int                                     party;
int                                     empathy;
int                                     fear;
int                                     carryCapacity;
Float                                   age;
Float                                   height;
Float                                   weight;
boolean                                 isWorking = false;

そして、コメントへの応答として、スレッドをどのように表示しているかの写真を次に示します。 ここに画像の説明を入力

4

1 に答える 1

2

一部のコードがまだ不足しているため、最初にいくつかの仮定を列挙します。いずれかが保持されない場合、以下の私の答えは間違っている可能性があります。

  1. run()あなたが与えたメソッドはJobクラス内にあります。
  2. あなたが参照する「キャンセル」ボタンはstopJob JButton

Job最初の実行後に再起動するために同じインスタンスを再利用する場合、基本的な問題はrun()メソッドが終了することです。whileをチェックするループがありますが!killFlag、そのループが終了すると (つまり、ジョブがキャンセルされて)、最初に戻って後続の状態が再び実行を開始するkillFlag == trueのを待つ原因はありません。goFlag == true(また、メソッドのstopJob節が でactionPerformed()何かをする必要があるかどうかを検討してくださいgoFlag。)

一方、Job再起動されたジョブを表す新しいインスタンスを作成する場合は、それを行うコードを示していません。

上記の診断では、意図的に少しあいまいにしていますが、それは、あなたが自分で物事を理解できるようにするためです。これが最善の学習方法です。:) さらに詳細が必要な場合は、LMK だけをコメントで提供してみてください。

于 2013-07-14T03:00:04.510 に答える