2016-11-01 27 views
0

私は親プロセスとして機能するクラスを持っています。実行中、多くの子プロセスを作成し、それらを同時に実行します。各子プロセスは、基本的にサービスに接続し、そこからデータを取得するHTTPクライアントです。親プロセスと子プロセスの間の通信

現在のところ、子プロセスのいずれかが何らかの理由で動作を停止した場合、親プロセスは同じ子プロセスを再起動して接続を再確立します。

子プロセスの切断は、いくつかの原因によって発生する可能性があります。私は子プロセスから親プロセスへの切断の理由を伝え、切断の理由(ソケット読み取り失敗、404未発見、401未許可など)に基づいて、親プロセスがそれに応じて行動するようにしたいと思います。

可能ですか?それを行う最短/最善の方法は何でしょうか?任意の助けをいただければ幸いです

public class Parent { 
public static void main(String[] args){ 
    List<Process> PRlist = new ArrayList<Process>(); 
    List<String[]> commandsList = new ArrayList<String[]>(); 
    DateTimeFormatter frmt = DateTimeFormatter.ofPattern("hh:mm:ss"); 

    if (args.length == 2 && args[0].matches("-f")){ 
     String dir = System.getProperty("user.dir"); 
     String path = dir + "/" + args[1]; 
     try { 
      FileReader fr = new FileReader(path); 
      BufferedReader bf = new BufferedReader(fr); 

      String line = ""; 
      while ((line = bf.readLine()) != null){ 
       String[] tk = line.split(" "); 
       String[] cmd = {"java", "-jar", "Child.jar", "-a", tk[0], "-p", tk[1], 
         "-u", tk[2], "-pw", tk[3], "-m", tk[4], "-s", tk[5]}; 
       Process pr = new ProcessBuilder().inheritIO().command(cmd).redirectInput(Redirect.INHERIT).start(); 
       PRlist.add(pr); commandsList.add(cmd); 
      } 
     } 
     catch (FileNotFoundException ex) {ex.printStackTrace();} 
     catch (IOException ex) {ex.printStackTrace();} 

     int streamnum = PRlist.size(); 

     while (true){ 
      for (int i = 0; i < streamnum; i++){ 
       if (!PRlist.get(i).isAlive()){ 
        PRlist.get(i).destroy(); 
        PRlist.remove(i); 
        try { 
         Process PR = new ProcessBuilder().inheritIO().command(commandsList.get(i)).redirectInput(Redirect.INHERIT).start(); 
         System.out.println(commandsList.get(i)[12] + " stream re-established at " + LocalDateTime.now().format(frmt)); 
         PRlist.add(i,PR); 
        } catch (IOException ex) {ex.printStackTrace();} 
       } 
      } 

      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException ex) {ex.printStackTrace();} 
     } 
    } else { 
     System.out.println("No stream file was specified."); 
    } 
}} 

: はここに私の親クラスです。

+0

Javaスレッドの代わりに別々のJVMインスタンスを使用する理由はありますか?よりメモリ効率が良く、問題を解決するのがはるかに簡単です。 –

+0

+1 to @BorisShchegolev。非常に興味深い推論がある場合を除き、ExecutorServiceを使用してこれを実行し、必要な情報を将来にわたって収集する必要があります。 – lscoughlin

+0

@BorisShchegolev私はちょうどこれを初めから書きましたが、特別な理由はありません。スレッドのプロセスを変更する場合は、私の問題をどのように解決することをお勧めしますか?どんな例? –

答えて

0

例として

いろいろ書い

if (!PRlist.get(i).isAlive()){ 
    int exitCode=PRlist.get(i).exitValue(); 
    //Do something with exitValue 

    PRlist.get(i).destroy(); 
    PRlist.get(i).destroy(); 
    PRlist.remove(i); 
    try { 
     Process PR = new ProcessBuilder().inheritIO().command(commandsList.get(i)).redirectInput(Redirect.INHERIT).start(); 
     System.out.println(commandsList.get(i)[12] + " stream re-established at " + LocalDateTime.now().format(frmt)); 
     PRlist.add(i,PR); 
     } catch (IOException ex) {ex.printStackTrace();} 
     } 

のような例は、より複雑である方法で作業することができますが、アイデアはテキスト処理によってerrorStreamにポストされている例外を見てみましょう。あなたはこのようにそれを行うだろうJavaのスレッドで

+0

ありがとう、私はこのアプローチを試してみます。 –

+0

そのアイデアは私のためにうまく動作します。ありがとうございました。 @BorisShchegolevが提示したアプローチを試してみると、私の記憶を救うかどうかが分かります。 –

+0

ようこそ。 私はとにかくスレッドアプローチは、あなたのサブプロセスをより詳細に制御できると思います。とにかく多くのスレッドを開くとリソースを消費する可能性があるので、私はメモリについてはわかりません – Massimo

0

たぶん、あなたはerrorStreamと

**public ProcessBuilder.Redirect redirectError()** 
Returns this process builder's standard error destination. Subprocesses subsequently started by this object's start() method redirect their standard error to this destination. The initial value is Redirect.PIPE. 
Returns: 
this process builder's standard error destination 

それとも

public abstract int exitValue() 
Returns the exit value for the subprocess. 
Returns: 
the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination. 
Throws: 
IllegalThreadStateException - if the subprocess represented by this Process object has not yet terminated 
+0

あなたのアイデアのためにいくつかの短い例を挙げることができますか? –

+0

例: – Massimo

+0

のようなものですか?私はあなたのコメントに何かがないと思う。 –

0

OK、:

class MyThreadedApp { 

    // main() here 

    /** 
    * Starting a new thread 
    */ 
    private void start() { 
     new Thread(() -> { 
      try { 
       new Worker().run(); 
      } catch (Exception ex) { 
       threadEnded(ex); 
      } 
     }).start(); 
    } 

    /** 
    * Handle errors 
    * 
    * @param ex Error 
    */ 
    private void threadEnded(Exception ex) { 
     System.out.println(ex.getMessage()); 
    } 
} 

/** 
* My worker thread 
*/ 
class Worker { 

    void run() throws IOException { 
     // Do my stuff here 
    } 
} 

だけでデータの流れを示すために、基本的な例です。実際には、lscoughlinに言及されている技術をいくつか使用することができます。

+0

ありがとう。私はあなたが何かをするためにエラーを利用するために 'Worker().'を実行するときに例外をキャッチしようとしているのを見ています。エラーがスローされない場合、同じコンセプトは機能しますか?たとえば、サーバが404と応答し、エラーがスローされなかった場合、スレッドは動作を停止しました。 –

+0

他の条件の場合、ワーカースレッドは 'HTTP 20x'例外をスローする必要があります。達成するのはかなり簡単です。 –

関連する問題