この投稿は、私がスイングに依存してブロックするためにスレッドとブールフラグを表示することを指示する学校の宿題に関連しています。マルチスレッドが正しく動作しない
私のアプリケーションは、それぞれがスレッドを含む「ジョブ」オブジェクトの束を作成します。それぞれの仕事はクリーチャーに属しています。クリーチャーは複数の仕事を持つことができますが、任意の瞬間に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();
}
}
最初に私はそれがIllegalMonitorStateException
を投げているので、それはtarget.notifyAll()
だと思ったが、私はスレッドをそれをコメントアウトしたときにオブジェクトが構築されますが、私は見たときになりますそれらのGUIの80%は、私からの介入なしで完全に表示され、他の20%は、そのクリーチャーがビジー状態であると述べています。
私はこれがkillフラグをあまりにも早くポップするからだと思っていましたが、私がそれを下に移動したり削除したりしても症状は依然として残ります。私は現時点で導入されており、ここにはプログラマーはいません。あなたが提供できるアドバイスは、世界を意味します。
私がスレッドとやりとりするために使用する方法は、私が十分な情報を提供していることを確認するためです。以下のメソッドは、スレッドが実行されているかどうかによって変更されるボタンで動作します。
これは私を殺しています。私はこれを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;
そして、ここでコメントへの応答では、私がスレッドを表示していますかの写真です:
新しいコードでは、より高いレベルの並行性の抽象化を使用する必要があります。スレッドではなく、タスクとエグゼキュータの観点からプロジェクトを定義する必要があります。 wait、notify、およびnotifyAllを正しく使用することは特に困難です。あなたのスレッドを調整する方法を議論する方法は、おそらくCountDownLatchを使うべきです。独自のセマフォーフラグは、少なくともあなたがそれらに加えた更新が他のスレッドに見えることを保証していないので、少なくともvolatileで宣言する必要があります。 – scottb
GUIの表示がありますが、フレームワークの識別はありません。スイングを使用している場合は、[スレッドの同時実行性](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)を参照して、単一スレッドのルールに違反していることを強くお勧めします。 – MadProgrammer
target.notifyAllはsynchronizedブロック内から実行する必要があります。notifyAllはモニターロックが動作するようにする必要があります。 – MadProgrammer