プロが教えるわが家の防犯対策術!

JAVAでプログラムを書く上で、Aという処理が終了次第、Bという処理を実行したい場合どうすればいいのでしょうか?
/////////////////////////////////////////////////////////////////
例えば、
・ファイルにデータを出力する。(例えば、バッチファイルhoge.batとして)
その後、すぐに
・そのバッチファイルを実行する命令を書く(Runtime.exec(hoge.bat);
/////////////////////////////////////////////////////////////////
このプログラムを実行した場合、スレッドAがファイルにデータを出力し終わる前に勝手にスレッドBが作られ、Runtime.exec(hoge.bat);が実行されてしまいます。正しくスレッドAが終了し終わった後にスレッドBが実行し始めるようにするにはどうすればいいのでしょうか?教えてください。お願いします。

A 回答 (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();
}
}

}
    • good
    • 0

回答2 について。



いいかげんな回答をしてすいません。
こんなコードじゃ絶対動かないですね。

それで、ちゃんとした回答をしようと、色々考えてたのですが、
どうしても、長くなってしまいます。
とりあえず、テスト済みのコードを載せますので、
質問等あったら改めておねがいします。
    • good
    • 0

あと、処理にもよりますが、ただの 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();
}
}
    • good
    • 0

ただのループだと、オーバーヘッドが大きいので、


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();
}

}
    • good
    • 0
この回答へのお礼

すごいわかりやすいソースをありがとうございます。
非常に助かりました。
僕はこの業界に足を踏み入れたいと考えている大学生なので、あなたのプロフィールの「一般人」というのを見ると自分が情けなくなります。
とにかく、ありがとうございます。感謝感謝です。

お礼日時:2002/03/20 18:10

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次第ですね…

参考URL:http://java.sun.com/products/jdk/1.2/ja/docs/ja/ …
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!