• ベストアンサー

スレッドについて

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

  • Java
  • 回答数5
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • Harry_
  • ベストアンサー率55% (36/65)
回答No.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)
回答No.4

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

  • Harry_
  • ベストアンサー率55% (36/65)
回答No.3

あと、処理にもよりますが、ただの 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)
回答No.2

ただのループだと、オーバーヘッドが大きいので、 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(); } }

tomatosuki
質問者

お礼

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

noname#6248
noname#6248
回答No.1

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/api/java/lang/Thread.html,http://www.gimlay.org/~javafaq/javafaq.html

関連するQ&A

  • Javaプログラムからバッチ起動

    Runtimeクラスを使用し、バッチファイルをJavaプログラム内で呼び出す処理を実装しました。Javaにより呼び出されるバッチファイル(X.bat)は、他の2つのバッチファイル(A.bat、B.bat)を呼び出すようにプログラムされています。ここで質問なのですが、実際にこのJavaプログラムを実行しX.batを呼び出し、最終的にA.bat、B.batが呼ばれているかどうかの確認をしたところ、どうもB.batが呼ばれずにA.bat終了後、処理が終了してしまっているなのですが、この原因についてご教授いただきたく質問いたしました。

    • ベストアンサー
    • Java
  • バッチファイルで他のバッチファイルを呼び出した後、元に戻ってこれない。

    バッチファイルで他のバッチファイルを呼び出した後、元に戻ってこれない。 バッチファイルでほかのバッチファイルを呼び出した後の処理で困っています。 どうぞ教えてください。 「A.bat」というバッチファイルを実行すると、「1.bat」というバッチファイルを 実行させ、「1.bat」の実行結果によって、処理を分岐させたいと考えています。 「1.bat」をcallで呼び出し、実行はできたのですが、「1.bat」は最後にエンタキーを 押さないと終了しないようになっています。そのため、「エンターキーを押して終了させて ください」というメッセージが出たままの画面で終わってしまい、「A.bat」に帰ってくることが できません。 「1.bat」は中身を扱えないようにしてあるバッチファイルなので、こちらでエンターキーを 押さずに終了させるようにはできません。何かいい方法はないでしょうか?

  • スレッドについてお教えください。

    スレッドについてお教えください。 今、画面のプログラムより、帳票を出力しています。 帳票の出力に時間がかかるため画面のプログラムとは非同期に 別スレッドにして帳票を出力しようと考えたのですがこの場合 一つの帳票の処理中に同じ要求が複数来た場合、スレッドは 複数立ちあがってしまい帳票の順番が狂ってしまうものと 思います。 これを要求はキューしていくが、処理は順次行う(1処理終了後に 次の要求を処理する)ということは可能なのでしょうか? お願いいたします。

  • java スレッドの作り方

    はじめまして☆ 課題で、「あるディレクトリのデータファイル(テキストファイル)を定期監視し、ファイルがあれば読み取って出力するjavaプログラムを作成しなさい」と出されました。 そこで、定期時間に繰り返し監視しながら、ファイルがあれば処理するために、ファイル処理スレッドを作りたいのですがスレッドを作ったことが無く、まったくわかりません(>_<) 誰か教えてください!!

  • .batファイルが実行できません[VB2005]

    お世話になってます。 VB2005にて、.batファイルの中身を書換え、他アプリケーションを 実行する処理を行っています。 しかし.batの書換えは正確に行われているのですが .bat実行中プロンプト内に出力されたテキストと異なる文字列が入っており 処理が完了しませんでした。 正しく処理するにはどのようにしたらよろしいでしょうか。 コードは下記の通りです。 'BATCHファイルの書換え処理 Dim Bat_f As New System.IO.StreamWriter(Cur_dir + "LT-AutoP1.BAT", False, System.Text.Encoding.Default) For Each line As String In ListBox1.Items Bat_f.WriteLine("CALL ACLT " + line + " /b AutoP.scr") Next Bat_f.Close() Dim psInfo As New ProcessStartInfo() psInfo.FileName = "C:\Program Files\AutoCAD LT 2002\LT-AutoP1.BAT" ' 実行するファイル psInfo.CreateNoWindow = False psInfo.UseShellExecute = False Process.Start(psInfo) 尚、正確に出力された.BATを直接ダブルクリックすると正常に処理されます。 CALL ACLT Z:\hoge\hoge1\hogehoge.dwg /b AutoP.scr コマンド実行中は下記のように表示されていました Z:\hoge\hoge1\>CALL ACLT Z:\hoge\hoge1\hogehoge.dwg /b AutoP.scr 'ACLT'は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません

  • Threadについて

    細かい質問なのですが、 1.一つのthreadを走らせるプログラムを2つ(二回)走らせるのと、 2.同じthreadを2つ走らせるプログラムを一つ走らせるのでは どう違うのでしょうか? 1(●)(●) 2(●●) 一応伝えにくいのですがこの違いについて質問したくなった経緯は以下です。 現在javaでUSB経由の音声の取得を行っています。マイクから拾った音声をそのままイヤホンに出力するプログラムです。USBは2つついています。(仮にA,Bとさせていただきます) 前者の一つのthreadを走らせるプログラム2つですと、まずUSB[A]をライン入力の音源として一つ走らせた後に音源をBに変えてからもう一つを走らせると出力側は2つの音声を同時に再生してくれます。 しかし、後者の場合、Aが選択されている状態で一つスレッドを動かし音源をBに選択し直してから次のスレッドを動かすプログラムにしているにも関わらずBの音声は取得されず、Aのみとなってしまいます。おそらくAを二倍?拾っています。 もし質問内容に違いがなければこのようなことは起きないかと思っています。単純に自分の技術不足かもしれませんが・・・・ 説明が上手く出来なかったのですが、質問は以上です。 特に音が一つになったことは分かりづらかったら気にしないでください。違いが分かればうれしいです。

  • VBAから複数のバッチファイルを実行する際に、1つの処理が終了するまで

    VBAから複数のバッチファイルを実行する際に、1つの処理が終了するまで次の処理を待機させる方法について こんにちは。VBA初心者です。 Shell関数を使って複数のバッチを連続して実行するプログラムを書きたいのですが、前のバッチ処理が終了する前に次のバッチが実行されてしまいエラーになってしまいます。 1つのバッチ処理が終了するまで、次の処理を待機させるようなことは可能でしょうか。 具体的には、B列に「test_01.txt」「test_02.txt」... といったファイル名が入力されていて、隣のA列に何らかの文字/記号があった場合は、指定されたバッチ(ファイル名.bat)が実行されるということをやりたいと考えています。 以下のようなプログラムを書いてみましたが、実行するバッチが複数になるとうまくいきせん。 どうしたら問題を回避できるか、ご教示いただけないでしょうか。 よろしくお願いします。 Sub バッチを実行() i = 7 'リストの開始行 Const myPath As String = "D:\sample_batch\"   Const endPath As String = ".bat"  For i = 7 To 200 '7行目から200行目まで実行 If Cells(i, 1).Value <> "" Then Shell (myPath & Cells(i, 2).Value & endPath) End If Next End Sub

  • スレッドについて

    スレッドについて勉強中なのですが、簡単なスレッド作り、 スレッドの処理が終わってからメインの処理を行わせたくて 以下のようなプログラムを書いてみました。 そこで、WaitForSingleObjectを使ってスレッドが終了するのを 待ちたいのですが、WaitForSingleObjectではまってしまうようで sprintfのメッセージ(スレッドが止まってしまっている)が 表示されません。 WRITE関数の処理が終われば、、WaitForSingleObjectで処理が 戻ってくると考えているのですが…。 スレッドについてと、間違いについて教えてもらえないでしょうか? 宜しくお願いします。 main { if(!stop) {   File = CreateFile(...); g_hThead = CreateThread(NULL,0,WRITE,(LPVOID)NULL,0,NULL); g_stop = false; }else { g_stop = true; ::WaitForSingleObject(g_hThead, INFINITE); CloseHandle(File); CloseHandle(hThead ); } } void WRITE() { while(!g_stop) { WriteFile(...); } ...処理を行う sprintf("スレッドを終了します。") }

  • net use コマンドでのサーバ接続について

    初めまして。 現在、WINDOWS2003サーバ(Aサーバ)を使用して、サーバ内でBATファイルを実行しています。 BATファイルの実行方法は、別のWINDOWS2003(Bサーバ)のバッチファイルから Aサーバにnet useコマンドで接続し、AサーバのBATファイルを実行するというものです。 Aサーバには複数のバッチが存在し、同時にBサーバ、CサーバからAサーバの各BATファイル を実行しています。 そこで問題が発生しているのですが、BサーバからバッチファイルでAサーバのバッチファイルを実行している間に、同時にCサーバのバッチファイルからAサーバのバッチファイルを実行しようとしたところ、先に実行されていたBサーバのバッチの処理が突然終わってしまい(Aサーバへの接続が切れた?)、Cサーバのバッチだけが実行される状態になってしまいます。 BサーバのバッチとCサーバのバッチを同時に実行することはできないのでしょうか? そもそもAサーバにnet useコマンドで複数のサーバから接続できないということでしょうか? ちなみにサーバは複数ありB,Cサーバ以外にも5つほどのサーバで同時にAサーバに接続を行いたいと思っています。 かなりはまって困っています。 わかる方ご教授いただけますでしょうか。よろしくお願いします

  • 複数の処理の終了を待ちたい

    お世話になります。以下、教えていただけますでしょうか? バッチファイル(A.bat)を作成しています。 そのなかで、a,b,c,dの複数のプログラムを、前処理の終了を待たずに起動させ、a,b,c,d全てが終了するのを待って、eというプログラムを実行させたいのです。 --------------- start a start b start c start d --------------- この記述で、a,b,c,dが一度に起動することは確認できました。 しかし、この後の、「a,b,c,d全ての終了を待ってeを起動させる方法」というのが分かりません。 教えていただけますでしょうか? それとも、そもそも、バッチでは実現不可能なのでしょうか?

専門家に質問してみよう