こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Java:スレッドでエラー発生時に処理を終わらせる

以下の事が出来ずに悩んでいます。

これ参考になるかな?
というようなWEBページ等がありましたら、教えていただけると助かります。


■やりたいこと
・aaa.javaから、「スレッド1」「スレッド2」「スレッド3」の処理を呼び出し、それぞれのスレッドで処理を実行する。
・全てのスレッド処理が完了したら、次の処理へ進む。
・「スレッド1、2、3」で、何かしらのエラーが発生した場合は、「aaa.java」の処理を終わらせる。

■現状
・aaa.javaから、「スレッド1、2、3」の処理を呼び出し、それぞれ処理を実行させる事は出来た。
・すべてのスレッドが完了したら次の処理へ進む事は出来た。
・「スレッド1、2、3」のどこかでエラーが発生した場合でも、処理の完了となり、「次の処理」へ進んでしまう。


もうちょっと細かい事を書くと、各スレッドでは、それぞれデータ作成のSQLを実行する処理をさせているのですが、
そのSQLが何かしらの要因でエラーで戻ってきた場合、次の処理へ進んでしまうとまずいです。
そのため、どこかのスレッドのSQLがエラーになったら、スレッドを呼び出した元の「aaa.java」でエラー・終了。となるようにしたいです。

一応、各スレッドでSQLのエラーとなった場合には「catch」に飛んでる。状態ではあるのですが、aaa.java側に戻って終わらせる事が出来ず。。。

ソースはだいぶ削りましたが、参考に以下記載します。
(削りすぎている可能性もありますが、その際はごめんなさい。)

すみませんが、よろしくお願いします。



----------------------------------------
aaa.java

  public void Sql_Exec() throws SQLException, IOException {

    /*
    ループ条件の取得。(省略)
    */

    //ループ処理。
    for (ループ条件(省略)) {

      //スレッドの呼び出し。
      //スレッド1
      Thread_1 exec_1 = new Thread_1(引数もろもろ);
      Thread thr_1 = new Thread(exec_1);
      thr_1.start();

      //スレッド2
      Thread_2 exec_2 = new Thread_2(引数もろもろ);
      Thread thr_2 = new Thread(exec_2);
      thr_2.start();

      //スレッド3
      Thread_3 exec_3 = new Thread_3(引数もろもろ);
      Thread thr_3 = new Thread(exec_3);
      thr_3.start();

      try {
        //全てのスレッドが終わるまで待つ。
        thr_1.join();
        thr_2.join();
        thr_3.join();
      } catch (InterruptedException e) {
        //例外処理
        e.printStackTrace();
      }
    }
  }

----------------------------------------
スレッド1~3.java

public class Thread_1 extends Thread{

  public void run(){

    /*
    ループ条件の取得。(省略)
    */
    
    //ループ処理。
    for (ループ条件(省略)) {
      try (Connection con1 = DB接続。) {
        String sql1 = 実行SQL取得;
        PreparedStatement pstmt1 = con1.prepareStatement(sql1);
        int aaa = pstmt1.executeUpdate();
        con1.close();
      } catch (SQLException | IOException | JAXBException e) {
        e.printStackTrace();
        throw new RuntimeException("例外!");
      }
    }

  }
}

----------------------------------------

投稿日時 - 2019-03-04 19:16:49

QNo.9593678

困ってます

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

少し無理矢理な感じはありますが、
メインスレッドでマップなどを使ってエラーを管理すればよろしいかなと思います。
Mainクラスはaaaクラスに、CustomThread1などはそれぞれThread_1などに読み替えてみてください。


import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Main {

public static void main(String[] args) {

Map<String, Exception> errors = new ConcurrentHashMap<>();

CustomThread thread1 = new CustomThread1(errors);
CustomThread thread2 = new CustomThread2(errors);
CustomThread thread3 = new CustomThread3(errors);

thread1.start();
thread2.start();
thread3.start();

try {
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
// 割り込み発生時。今回は何もしない
}

if (!errors.isEmpty()) {
// いずれかのスレッドでエラー発生。Exceptionを取るもよし、煮るなり焼くなりお好きにどうぞ。
System.out.println("エラー発生");
System.exit(-1); // この例ではシステム強制終了(非推奨)
}

System.out.println("正常終了");

}

private static abstract class CustomThread extends Thread {

protected final Map<String, Exception> errors;

protected CustomThread(Map<String, Exception> errors)
{
this.errors = errors;
}

public Map<String, Exception> getErrors()
{
return errors;
}

@Override
public abstract void run();
}

private static class CustomThread1 extends CustomThread {

public CustomThread1(Map<String, Exception> errors) {
super(errors);
}

@Override
public void run() {
try {
// 何らかの処理
Thread.sleep(1000);

} catch (Exception e) {
// ロールバックなどの処理

errors.put("Thread1", e);
}
}
}

private static class CustomThread2 extends CustomThread {

public CustomThread2(Map<String, Exception> errors) {
super(errors);
}

@Override
public void run() {
try {
// 何らかの処理
Thread.sleep(2000);

throw new Exception(); // エラー発生をシミュレート
} catch (Exception e) {
// ロールバックなどの処理

errors.put("Thread2", e);
}
}
}

private static class CustomThread3 extends CustomThread {

public CustomThread3(Map<String, Exception> errors) {
super(errors);
}

@Override
public void run() {
try {
// 何らかの処理
Thread.sleep(3000);
} catch (Exception e) {
// ロールバックなどの処理

errors.put("Thread3", e);
}
}
}

}

投稿日時 - 2019-03-08 16:53:42

お礼

お礼が遅くなり申し訳ありませんでした。
回答のほど誠にありがとうございました。

おかげ様で、やりたかったことを実装することが出来たので、とても助かりました。
なかなかJavaに慣れないなぁ。。。

投稿日時 - 2019-04-03 10:21:31

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

https://codezine.jp/article/detail/85
この辺を参考にされてはいかがでしょうか。

投稿日時 - 2019-03-05 20:35:57

お礼

回答ありがとうございました。
全然勉強不足のようですので、読んで勉強させていただきます。

投稿日時 - 2019-04-03 10:23:09

ANo.1

以下の例外処理に何が書かれているのか分かりませんが、
その部分に break; ではダメなんでしょうか。

try {
//全てのスレッドが終わるまで待つ。
thr_1.join();
thr_2.join();
thr_3.join();
} catch (InterruptedException e) {
//例外処理
e.printStackTrace();
}

投稿日時 - 2019-03-05 10:23:34

お礼

回答ありがとうございました。
ダメでした。。。
勉強不足でやってることも上手く説明できないのは問題ですね。
勉強するようにします。

投稿日時 - 2019-04-03 10:26:00

あなたにオススメの質問