私はwaitとnotifyAllの仕組みを理解し、ロードブロッキングを達成しました。waitとnotifyAllを使用するとJavaプログラムがフリーズします
このプログラムは、長いテキスト文書をダウンロードし、複数のスレッドを開始して文字数をカウントし、合計を出力します。
スレッド実行を制御してアルファベット順に完了させるために、waitとnotifyAllを使用しています。ここにコードがあります。私はその問題の説明に従います。
public class Test {
public static void main(String[] args) {
//code that reads in the data
LongTask a = new LongTask(buffer, 'a', "Thread_a", 0);
a.start();
LongTask b = new LongTask(buffer, 'b', "Thread_b", 1);
b.start();
//Repeat code for all other characters
a.join();
System.out.println("Alphabet count is: " + SharedResults.getResults());
LongTaskクラスは、コンストラクタと実行()
public class LongTask extends Thread {
//Instance variables created here
//LongTask constructor
public LongTask (StringBuffer buffer, char target, String name, int turn)
{
super(name);
this.sharedData = sharedData;
inputData = buffer;
this.target = target;
this.turn = turn;
}
//Run method iterates through input data and counts matching characters,
//then calls addToResults
public synchronized void run()
{
//Thread t = Thread.currentThread();
String name = this.getName();
int runTurn = this.turn;
System.out.println(name + " running - Turn " + runTurn);
Integer count = 0;
for (int i = 0; i < inputData.length(); i++) {
if (inputData.charAt(i) == target) {
count ++;
}
}
ResultsEntry newResult = new ResultsEntry(count, target);
SharedResults.addToResults(newResult, turn);
}
}
SharedResultsクラスは、配列に結果が追加されますが含まれています。 addToResultsメソッドはこのアクションを実行し、同期を制御します。
public class SharedResults extends Thread{
//Code that creates array
//Code for SharedResults constructor
public synchronized static void addToResults(ResultsEntry newResult, int turn)
{
Integer resultsCount = newResult.getCount();
char resultsTarget = newResult.getTarget();
Thread t = Thread.currentThread();
/*
* Turn number is compared to the size of the results array to control the
* order of execution.
*/
while (turn != results.size()){
try {
System.out.println("Wait printout");
t.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(t.getName() + " is adding " + newResult);
SharedResults input = new SharedResults(resultsCount, resultsTarget);
System.out.println("Cumulative Results are " + results);
t.notifyAll();
}
この手順をデバッグで見ると、次のようなことが起こります。 - 入力が実行され、すべてのLongTaskスレッドが(Thread_aがaddToResultsを実行するための最初のスレッドでなければなりません)
- いくつかのスレッド(ないThread_a)
を開始するには、addToResultsの中の評価をヒットし、
を続行しないでください - Thread_aは評価中にヒットし、完全に実行されます。
-Thread_eは、「プリント待ち」(スレッドが待機していることを通知するデバッグ機能)を実行し、プログラムがハングアップします。
私は正しく待ち時間を設定していないように見えます。 sysoutに追加するまで、プログラムは実際に正しく機能していました(または、そうであるように見えました)。ここで起こっていることは何ですか?
ここでのロックの仕組みは混乱します。ロックを使用して共有データ構造(データ構造がロックを使用して自己へのアクセスを制限する)を保護する場合、スレッドによってロックが行われるのではなく、混乱が少なくなります。 –
Re、 "スレッド実行を制御するためにwaitとnotifyAllを使用して、アルファベット順に完了します。"あなたが間違った方向にあなたの旅を始めているように聞こえます。あなたが特定の順序で物事をするようにスレッドを強制すると、スレッドのアイデアを覆すことになります。これは、同時に(つまり、特に順序なく)何かを行うことです。) –
'public synchronized void run()'これは絶対に悪い考えです。 –