スレッドを処理するさまざまな方法の影響を示すデモ プログラムを開発しています。私はchar配列を取り、各charをStringBuilderに送信する名前を作成するという単純なタスクを使用しています.StringBuilderはNameBuilderと呼ばれる実行可能オブジェクトを呼び出します。これは、同期されたメソッドを持つletterAdderクラスと静的StringBuilder変数を使用して名前をそのまま保持します構築されました。この構造は、Bruce Eckel 著「Thinking in Java」の WaxoMatic の例に大まかに基づいています。
notifyAll() メソッドに使用しているコードは次のとおりです。
import java.util.List;
import java.util.concurrent.*;
class LetterAdder{
public static StringBuilder currName = new StringBuilder();
public static boolean busyAdding = false;
public synchronized void addLetterSynchWithNotifyAll(char letter) throws InterruptedException{
while (busyAdding){
System.out.println("Letter " +letter+" has to wait");
wait();
}
busyAdding=true;
System.out.println("About to add " + letter + " - ");
currName.append(letter);
System.out.println("name is now " + currName);
busyAdding=false;
}
public synchronized void doNotifyAll(char letter) throws InterruptedException{
System.out.print(letter + " is notifying all");
notifyAll();
}
}
class NameBuilder implements Runnable{
private LetterAdder adder = new LetterAdder();
private char nextLetter;
public NameBuilder(char nextLetter){
adder = new LetterAdder();
this.nextLetter=nextLetter;
}
public void run(){
try{
adder.addLetterSynchWithNotifyAll(nextLetter);
adder.doNotifyAll(nextLetter);
} catch (InterruptedException e) {
System.out.println("Letter "+nextLetter+" interrupted!");
}
//tie up thread for specified time to ensure other threads go to wait
try{
TimeUnit.SECONDS.sleep(1);
} catch(Exception e){}
}
}
public class NotifyDemo {
public static void main(String[] args) {
char[] chars = {'M', 'a','r','t','i','n'};
ExecutorService pool = Executors.newCachedThreadPool();
for (int i=0; i<chars.length; i++){
NameBuilder builder = new NameBuilder(chars[i]);
pool.execute(builder);
}
System.out.println("\nWill shutdown thread pool in 20 seconds");
try {
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedException e) {}
System.out.println("\nAbout to shutdown thread pool ");
List<Runnable> tasks = pool.shutdownNow();
if (!tasks.isEmpty()){
for (Runnable r: tasks){
System.out.println("Uncompleted task: "+r.toString());
}
}
}
}
/** Output
About to add M -
Letter a has to wait
name is now M
Letter r has to wait
M is notifying allLetter t has to wait
About to add i -
Will shutdown thread pool in 20 seconds
Letter n has to wait
name is now Mi
i is notifying all
About to shutdown thread pool
Letter a interrupted!
Letter t interrupted!
Letter n interrupted!
Letter r interrupted!
*/
出力に出力されたステートメントからわかるように、文字が busyAdding モニターに到達して待機メッセージを出力するとブロックされますが、notifAlly() が送信されても待機状態から抜け出すことはありません。
また、中断されたスレッドが shutdownNow() ステートメントによって返されるリストに表示されることを期待しますが、リストは空です。
私は明らかな何かが欠けていると感じています.誰かが私がここで間違っていることを見つけることができますか?