- ベストアンサー
スレッドについて
JAVAでプログラムを書く上で、Aという処理が終了次第、Bという処理を実行したい場合どうすればいいのでしょうか? ///////////////////////////////////////////////////////////////// 例えば、 ・ファイルにデータを出力する。(例えば、バッチファイルhoge.batとして) その後、すぐに ・そのバッチファイルを実行する命令を書く(Runtime.exec(hoge.bat); ///////////////////////////////////////////////////////////////// このプログラムを実行した場合、スレッドAがファイルにデータを出力し終わる前に勝手にスレッドBが作られ、Runtime.exec(hoge.bat);が実行されてしまいます。正しくスレッドAが終了し終わった後にスレッドBが実行し始めるようにするにはどうすればいいのでしょうか?教えてください。お願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
(1) スレッドの実行用クラス public class Test { private boolean finished; private ExeFile exefile; class Thread_A extends Thread { public void run() { try { exefile.create(); // ファイルを作成 } catch (Exception ex) { ex.printStackTrace(); } } } class Thread_B extends Thread { public void run() { try { exefile.exec(); // スレッドAの作成したファイルの中身を表示 } catch (Exception ex) { ex.printStackTrace(); } } } public void test() { exefile = new ExeFile(); new Thread_A().start(); new Thread_B().start(); } public static void main(String[] args) { Test t = new Test(); t.test(); } } (2) 複数のスレッドからアクセスされる可能性のある処理クラス import java.io.*; public class ExeFile { private File file; private boolean created; public synchronized void create() throws InterruptedException { file = new File("c:/test.txt"); try { OutputStream out = new FileOutputStream(file); byte[] text = "It's a test program.".getBytes(); out.write(text); // ファイルにテキストを書き込む } catch (IOException ex) { ex.printStackTrace(); } Thread.sleep(3000); // wait,notify の動きが明瞭に確認できるよう3秒スリープ created = true; notify(); // wait中のスレッドに通知 } public synchronized void exec() throws InterruptedException { while (!created) wait(); // ファイルが作られてなかったら待機 try { InputStream in = new FileInputStream(file); int size = (int)file.length(); byte[] text = new byte[size]; in.read(text); // ファイルの読み込み System.out.println(new String(text)); // ファイルの内容表示 } catch (IOException ex) { ex.printStackTrace(); } } }
その他の回答 (4)
- Harry_
- ベストアンサー率55% (36/65)
回答2 について。 いいかげんな回答をしてすいません。 こんなコードじゃ絶対動かないですね。 それで、ちゃんとした回答をしようと、色々考えてたのですが、 どうしても、長くなってしまいます。 とりあえず、テスト済みのコードを載せますので、 質問等あったら改めておねがいします。
- Harry_
- ベストアンサー率55% (36/65)
あと、処理にもよりますが、ただの join() でいいかも知れないです。 public class Test2 { class Thread_A { public void run() { // 処理A; } } class Thread_B { public void run() { // 処理B; } } public void test() { Thread th = new Thread_A(); th.start(); th.join(); new Thread_B(); } }
- Harry_
- ベストアンサー率55% (36/65)
ただのループだと、オーバーヘッドが大きいので、 wait() と notify() を使ったらどうでしょう。 下がサンプルです。finishedフィールドと、wait()をくくってるループは なくても正常に動くと思いますが、wait()は保険のため ループでくくるのが定石になってます。 mainメソッドは省略です。 public class Test { private boolean finished; class Thread_A extends Thread { public void run() { // 処理A; finished = true; nofity(); } } class Tread_B extends Thread { public void run() { while(!finished) { wait(); } // 処理B; } } public void test() { new Thread_A().start(); new Thread_B().start(); } }
synchronizedを使用すればいいように思えますが… スレッドにフィールド(finished)を追加してwhileループを使用してみてはいかがですか? 少々長いですがサンプルソースを載せます。 public class ThreadTest { class Class1 extends Thread { public boolean finished = false; public void run( ) { finished = false; //処理1 finished = true; } } class Class2 extends Thread { public boolean finished = false; public void run( ) { finished = false; //処理2 finished = true; } } Class1 class1; Class2 class2; // コンストラクタ public ThreadTest() { class1 = new Class1(); class2 = new Class2(); } // スレッド実行部 public void start() { class1.start(); // ↓追加部分 while(!class1.finished){}//実行中は無限ループ class2.start(); } public static void main(String[] args) { ThreadTest test = new ThreadTest(); test.start(); } } あとは…参考URL次第ですね…
お礼
すごいわかりやすいソースをありがとうございます。 非常に助かりました。 僕はこの業界に足を踏み入れたいと考えている大学生なので、あなたのプロフィールの「一般人」というのを見ると自分が情けなくなります。 とにかく、ありがとうございます。感謝感謝です。