以下のようにfor文でスレッドを4つ立ち上げるプログラムを組みました。
for( int i = 0; i < 4; i++ ) {
//メッセージを送るスレッドをたてる
Fieldmsg fieldmsg = new Fieldmsg(socket);
fieldmsg.start();
fieldmsg.join();
}
fieldmsg.join(); が食い止めているので、この場合は1つのスレッドが終わるまで
次のスレッドは立ち上がらないと思います。
問題は、4つのスレッドすべてが立ち上がり、4つが終了するのを見届けたい場合です。
Fieldmsg fieldmsg;
for( int i = 0; i < 4; i++ ) {
//メッセージを送るスレッドをたてる
fieldmsg = new Fieldmsg(socket);
fieldmsg.start();
}
fieldmsg.join();
こうしたらどうなるでしょうか?
それとも4つのスレッド全部にフラグを立てるような仕組みをいれてそれを監視するという方法がいいのでしょうか?
4つのスレッドすべてが終了するまで待つのに
fieldmsg.join();
ではいけません。
なぜなら、fieldmsg が指しているのは最後に作ったスレッドだけだからです。
List<Fieldmsg> fieldmsgs = new ArrayList<Fieldmsg>(); for( int i = 0; i < 4; i++ ) { //メッセージを送るスレッドをたてる Fieldmsg fieldmsg = new Fieldmsg(socket); fieldmsg.start(); // 終了監視用のリストに今立てたスレッドを格納 fieldmsgs.add(fieldmsg); } // すべてのスレッドの終了を監視 for (Fieldmsg fieldmsg : fieldmsgs) { fieldmsg.join(); }
4つ作るなら4つともスレッドへの参照を取っておいて、すべてについて終了を待ってあげる必要があります。
Thread#join() をスレッドの数だけ呼ぶ必要がある、というのは既に出てるので、別の方法を。
java.util.concurrent パッケージのクラスを使うと、もう少し簡単になります。
CountDownLatch が良いのかな...
public class Hatena { static class MyThread extends Thread { private CountDownLatch latch_; private String answer_; private int no_; MyThread(int no, latch) { no_ = no; latch_ = latch; } public void run() { try { Thread.sleep((int)(Math.random() * 10000)); } catch (InterruptedException e) { System.out.println(e); } answer_ = "hatena-" + no_; System.out.println("finish No." + no_); // カウントを一つ減らす latch_.countDown(); } public String getAnswer() { return answer_; } } public static void main(String[] args) { try { CountDownLatch latch = new CountDownLatch(4); for (int i = 0 ; i < 4 ; ++i) { MyThread th = new MyThread(i, latch); // 四回スタート th.start(); } // カウントがゼロになるまで待つ latch.await(); System.out.println("All Finish !!!"); /* む、結果を取るには Thread を保存しておかなきゃ駄目か... */ } catch (InterruptedException e) { System.out.println(e); } } }
public class Hatena { static class MyThread extends Thread { private CountDownLatch latch_; private SynchronousQueue<String> result_; private int no_; MyThread(int no, latch, result) { no_ = no; latch_ = latch; result_ = result; } public void run() { try { Thread.sleep((int)(Math.random() * 10000)); String answer = "hatena-" + no_; result_.put(answer); } catch (InterruptedException e) { System.out.println(e); } System.out.println("finish No." + no_); // カウントを一つ減らす latch_.countDown(); } public String getAnswer() { return answer_; } } public static void main(String[] args) { try { CountDownLatch latch = new CountDownLatch(4); SynchronousQueue<String> result = new SynchronousQueue<String>(); for (int i = 0 ; i < 4 ; ++i) { MyThread th = new MyThread(i, latch, result); // 四回スタート th.start(); } // カウントがゼロになるまで待つ latch.await(); System.out.println("All Finish !!!"); // 結果を取得する for (String s : result) { System.out.println("answer = " + s); } } catch (InterruptedException e) { System.out.println(e); } } }
四つのスレッドが全て終わるのを待ち合わせなくても良いなら、CountDownLatch も要らないですね。
for (int i = 0 ; i < 4 ; ++i) { (new MyThread(i, result)).start(); } for (int i = 0 ; i < 4 ; ++i) { // 計算が終わったものから、結果を取り出す String s = result.take(); System.out.println("answer = " + s); }
何か、すっきりしない感じだったので、追記しました。
ありがとうございました。大変参考になりました。
わざわざ、ありがとうございます!大変参考になりました!
2013/08/20 13:15:56さっそく組み込みました!