1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaのCallableはExceptionがcatchできない?

Last updated at Posted at 2021-03-30

仕事でCallableスレッドの処理がExceptionを拾えないのでRunnableに替えるという作業があったので本当にExceptionが取れないのか試してみました。

Callableの実装

package example;

import java.util.concurrent.Callable;

public class Call1 implements Callable<String> {

    // callの中に実際の処理を書く。
    public String call(){
	String nonNum = "null";
	System.out.println("init Call1");
	// Exceptionを発生させる
	System.out.println("print call " + Integer.parseInt(nonNum));
        return "Call";
    }
}

Runnableの実装

package example;

public class Run1 implements Runnable {

    // callの中に実際の処理を書く。

    public void run(){
	String nonNum = "run";
	System.out.println("init Run1");
	// Exceptionを発生させる
	System.out.println("print run " + Integer.parseInt(nonNum));
    }
}

CallableとRunnableの呼び出し

package example;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello World");
        // ExecutorServiceを生成
        ExecutorService ex = Executors.newSingleThreadExecutor();

	try {
	    // Executorにスレッド Call1() の実行を依頼
	    Future<String> futureResult = ex.submit(new Call1());
	} catch (Exception e) {
	    System.out.println("Catched Call1 Exception:" + e.getMessage());
	}

	try {
	    // Run1を実行
	    Run1 run = new Run1();
	    Thread thread = new Thread(run);
	    thread.start();
	} catch (Exception e) {
	    System.out.println("Catched Run Exception:" + e.getMessage());
	}
    }
}

コンパイル

$ javac example/Hello.java example/Run1.java example/Call1.java 

実行

$ java example.Hello                         
Hello World
init Call1
init Run1
Exception in thread "Thread-0" java.lang.NumberFormatException: For input string: "run"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at example.Run1.run(Run1.java:13)
	at java.base/java.lang.Thread.run(Thread.java:834)

RunnableのExceptionが表示されるが、CallableのExceptionはキャッチできないし、mainのtry catchでもキャッチできない。


しかし、Callableはget()した時にExceptionがキャッチできるとご指摘があり再度試してみました。
ご指摘くださった方々ありがとうございました。

mainは次の様に修正。

package example;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
    
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello World");
        // ExecutorServiceを生成
        ExecutorService ex = Executors.newSingleThreadExecutor();

	try {
	    // Executorにスレッド Call1() の実行を依頼
	    Future<String> futureResult = ex.submit(new Call1());
	    String ret; 
	    ret = futureResult.get();
	    System.out.println("ret=" + ret);
	} catch (InterruptedException|ExecutionException e) {
	    System.out.println("Catched Call1 Exception:" + e.getMessage());
	}

	// Run1を実行
	Run1 run = new Run1();
	Thread thread = new Thread(run);
	thread.start();
    }
}

コンパイルして実行すると。両方のExceptionを取得することができました。

 $ java example.Hello       
Hello World
init Call1
Catched Call1 Exception:java.lang.NumberFormatException: For input string: "null"
init Run1
Exception in thread "Thread-0" java.lang.NumberFormatException: For input string: "run"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at example.Run1.run(Run1.java:13)
	at java.base/java.lang.Thread.run(Thread.java:834)

うーむ。なぜCallableをRunnableに替える必要があったのか。

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?