Beispielcode, um drei Arten von Ausnahmen zurückzugeben.
import java.util.concurrent.*;
import java.util.*;
public class ExceptionDemo{
public static void main(String args[]){
int poolSize=1;
int maxPoolSize=1;
int queueSize=30;
long aliveTive=60;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
ThreadPoolExecutor executor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue);
List<Future> futures = new ArrayList<Future>();
for (int i=0; i < 5; i++){
futures.add(executor.submit(new RunnableEx()));
}
for (Iterator it = futures.iterator(); it.hasNext();){
try {
Future f = (Future)it.next();
f.get(4000,TimeUnit.MILLISECONDS);
}catch(TimeoutException terr){
System.out.println("Timeout exception");
terr.printStackTrace();
}
catch(InterruptedException ierr){
System.out.println("Interrupted exception:");
ierr.printStackTrace();
}catch(ExecutionException err){
System.out.println("Exeuction exception:");
err.printStackTrace();
Thread.currentThread().interrupt();
}
}
executor.shutdown();
}
}
class RunnableEx implements Runnable{
public void run() {
// code in here
System.out.println("Thread name:"+Thread.currentThread().getName());
try{
Random r = new Random();
if (r.nextInt(2) == 1){
Thread.sleep(2000);
}else{
Thread.sleep(4000);
}
System.out.println("eee:"+1/0);
}catch(InterruptedException irr){
irr.printStackTrace();
}
}
}
Ausgang:
Thread name:pool-1-thread-1
Timeout exception
Thread name:pool-1-thread-1
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Exeuction exception:
java.util.concurrent.ExecutionException: java.lang.ArithmeticException:/by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:202)
at ExceptionDemo.main(ExceptionDemo.java:20)
Caused by: java.lang.ArithmeticException:/by zero
at RunnableEx.run(ExceptionDemo.java:49)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
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)
Interrupted exception:
java.lang.InterruptedException
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
at java.util.concurrent.FutureTask.get(FutureTask.java:199)
at ExceptionDemo.main(ExceptionDemo.java:20)
Timeout exception
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
Thread name:pool-1-thread-1
at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Timeout exception
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
at ExceptionDemo.main(ExceptionDemo.java:20)
TimeoutException: Exception ausgelöst, wenn ein Blockierungsvorgang abläuft.
Im obigen Beispiel einige Aufgaben mehr Zeit nehmen (wegen 4 Sekunden Schlaf) und Sperrbetrieb von get()
auf Future
Entweder das Timeout erhöhen oder Runnable Aufgabe zu optimieren.
ExecutionException: Ausnahme ausgelöst, wenn Sie versuchen, das Ergebnis einer Aufgabe abzurufen, die durch Auslösen einer Ausnahme abgebrochen => Die Berechnung eine Ausnahme warf
In obigem Beispiel diese Exception
simuliert durch ArithmeticException:/by zero
Im Allgemeinen Sie sollten es fangen, beheben Sie die Ursache, wenn es trivial ist, wie im Beispiel zitiert.
InterruptedException: Wird ausgelöst, wenn ein Thread wartet, schläft oder anderweitig belegt ist und der Thread entweder vor oder während der Aktivität unterbrochen wird.
Im obigen Beispiel wird Exception
simuliert, indem der aktuelle Thread während ExecutionException
unterbrochen wird.
Im Allgemeinen sollten Sie es fangen handeln Sie nicht darauf.
Gibt es eine Möglichkeit zu verhindern, dass ExecutionException ausgelöst wird, wenn bei der Verarbeitung einer Aufgabe eine Ausnahme vorliegt. Auch wenn Sie die Exception in die Verarbeitung geworfen haben und diese verarbeiten, wird die Exception immer noch in ExecutionException umgewandelt und in den get-Modus geworfen. –
Gibt es eine Beziehung zwischen InterruptedException und ExecutionException, nur um zu wissen, welche zuerst zu fangen ist. In der SO-Frage fängt er zuerst die InterruptedException und dann die ExecutionException ab. Wird das Verhalten dasselbe sein, wenn wir die Reihenfolge tauschen? – prime
@prime: siehe https://stackoverflow.com/a/10964899/217324. Beide Ausnahmen erweitern die Ausnahme, keine ist spezifischer als die andere. Die Reihenfolge spielt in diesem Fall keine Rolle. –