execute:呼び出しに使用し、呼び出しを忘れます
submit:これを使用して、メソッド呼び出しの結果を検査Future
し、呼び出しによって返されたオブジェクトに対して適切なアクションを実行します
以下からのjavadoc
submit(Callable<T> task)
値を返すタスクを実行のために送信し、タスクの保留中の結果を表すFutureを返します。
Future<?> submit(Runnable task)
Runnableタスクを送信して実行し、そのタスクを表すFutureを返します。
void execute(Runnable command)
指定されたコマンドを将来のある時点で実行します。コマンドは、Executor実装の裁量で、新しいスレッド、プールされたスレッド、または呼び出しスレッドで実行できます。
の使用中は注意が必要submit()
です。タスクコードをtry{} catch{}
ブロックに埋め込まない限り、フレームワーク自体に例外を隠します。
コード例:このコードはを飲み込みArithmetic exception : / by zero
ます。
import java.util.concurrent.*;
import java.util.*;
public class ExecuteSubmitDemo{
public ExecuteSubmitDemo()
{
System.out.println("creating service");
ExecutorService service = Executors.newFixedThreadPool(10);
//ExtendedExecutor service = new ExtendedExecutor();
service.submit(new Runnable(){
public void run(){
int a=4, b = 0;
System.out.println("a and b="+a+":"+b);
System.out.println("a/b:"+(a/b));
System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
}
});
service.shutdown();
}
public static void main(String args[]){
ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
}
}
出力:
java ExecuteSubmitDemo
creating service
a and b=4:0
同じコードは()で置き換えることsubmit()
でスローされますexecute
:
交換する
service.submit(new Runnable(){
と
service.execute(new Runnable(){
出力:
java ExecuteSubmitDemo
creating service
a and b=4:0
Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:14)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
submit()の使用中にこれらのタイプのシナリオを処理するにはどうすればよいですか?
- タスクコード(RunnableまたはCallable実装のいずれか)をtry {} catch {}ブロックコードで埋め込む
- 実装する
CustomThreadPoolExecutor
新しいソリューション:
import java.util.concurrent.*;
import java.util.*;
public class ExecuteSubmitDemo{
public ExecuteSubmitDemo()
{
System.out.println("creating service");
//ExecutorService service = Executors.newFixedThreadPool(10);
ExtendedExecutor service = new ExtendedExecutor();
service.submit(new Runnable(){
public void run(){
int a=4, b = 0;
System.out.println("a and b="+a+":"+b);
System.out.println("a/b:"+(a/b));
System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
}
});
service.shutdown();
}
public static void main(String args[]){
ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
}
}
class ExtendedExecutor extends ThreadPoolExecutor {
public ExtendedExecutor() {
super(1,1,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
}
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
出力:
java ExecuteSubmitDemo
creating service
a and b=4:0
java.lang.ArithmeticException: / by zero
Runnable
ラップされるかどうかに依存するため、保証されないことに注意してくださいTask
。たとえば、Executor
実際にであるScheduledExecutorService
場合、タスクは内部でラップされ、Future
キャッチされなかっThrowable
たはこのオブジェクトにバインドされます。