我的代码段:
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
Task t = new Task(response,inputToPass,pTypes,unit.getInstance(),methodName,unit.getUnitKey());
Future<SCCallOutResponse> fut = executor.submit(t);
response = fut.get(unit.getTimeOut(),TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// if the task is still running, a TimeOutException will occur while fut.get()
cat.error("Unit " + unit.getUnitKey() + " Timed Out");
response.setVote(SCCallOutConsts.TIMEOUT);
} catch (InterruptedException e) {
cat.error(e);
} catch (ExecutionException e) {
cat.error(e);
} finally {
executor.shutdown();
}
我应该如何处理代码中的InterruptedException
和ExecutionException
?
在什么情况下,抛出这些异常?
答案 0 :(得分:35)
ExecutionException
和InterruptedException
是两回事。
ExecutionException
包装正在执行的线程抛出的任何异常,因此,如果您的线程正在执行某种导致IOException
被抛出的IO,那将被包装在{ {1}}并重新投入。
ExecutionException
并不表示出现任何问题。它是为您提供一种方法,让您的线程知道什么时候停止,以便他们可以完成当前的工作并优雅地退出。假设我希望我的应用程序停止运行,但我不希望我的线程丢弃他们正在做的事情(如果我做了它们的守护程序线程会发生什么)。因此,当关闭应用程序时,我的代码会在这些线程上调用中断方法,这会在它们上设置中断标志,下次这些线程等待或休眠时,它们会检查中断标志并抛出InterruptedException
,我可以用来摆脱线程所涉及的无限循环处理/休眠逻辑。(如果线程没有等待或休眠,它只能定期检查中断标志。)所以它是一个实例用于更改逻辑流的异常。您完全记录它的唯一原因是在示例程序中向您显示正在发生的事情,或者您是否正在调试中断逻辑无法正常工作的问题。
答案 1 :(得分:6)
InterruptedException
,将抛出 interrupt
。
ExecutionException
)本身会引发异常,则会抛出 Task
。
您希望如何处理这完全取决于您的应用程序。
编辑:这是一个被打断的示范:import java.util.concurrent.*;
public class Test
{
public static void main(String[] args) throws Exception
{
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(new SlowCallable());
executor.submit(new Interruptor(Thread.currentThread()));
try
{
System.out.println(future.get());
}
catch (InterruptedException e)
{
System.out.println("I was interrupted");
}
}
private static class Interruptor implements Callable<String>
{
private final Thread threadToInterrupt;
Interruptor(Thread threadToInterrupt)
{
this.threadToInterrupt = threadToInterrupt;
}
public String call() throws Exception
{
Thread.sleep(2000);
threadToInterrupt.interrupt();
return "interrupted other thread";
}
}
private static class SlowCallable implements Callable<String>
{
public String call() throws Exception
{
Thread.sleep(5000);
return "finished";
}
}
}
答案 2 :(得分:3)
IBM Developer Works文章Dealing with InterruptedException对如何处理InterruptedException
提出了一些建议。
答案 3 :(得分:0)
返回三种异常类型的示例代码。
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();
}
}
}
输出:
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:阻塞操作超时时抛出异常。
在上面的示例中,某些任务花费更多时间(由于4秒睡眠)以及get()
上Future
的阻止操作
增加超时或优化Runnable任务。
ExecutionException:尝试检索通过抛出异常而中止的任务的结果时抛出异常=&gt;计算引发了异常
在上面的示例中,此Exception
是通过ArithmeticException: / by zero
一般来说,你应该抓住它来解决根本原因,如果它在例子中引用是微不足道的。
InterruptedException:当线程正在等待,休眠或以其他方式占用时抛出,并且线程在活动之前或期间被中断。
在上面的示例中,通过在Exception
期间中断当前线程来模拟此ExecutionException
。
一般来说,你应该抓住它不要对它采取行动。