Future.get()总是被InterruptedException中断

时间:2010-11-24 15:27:07

标签: java null get future interrupted-exception

我在Java中遇到了Future.get()的WEIRD问题。它总是返回一个InterruptedException,但奇怪的是,Exception的原因是null,所以我不能告诉谁打断了我..

它变得更糟,因为我在调用get()之前检查,而Future必须完成的工作已经完成。

以下是负责输出的代码。 f是Future ,并且callable返回一个HashMap,其中Agent与其真正无关。对不起,如果有太多的印刷品,我只是想尽可能地提供信息。来自callable的调用方法现在是一个简单的System.out.println("Hola soy agente"),正如您将看到的那样,打印出来,这意味着可调用的函数不会导致异常

以下是代码:

try
    {
        System.out.println(f.isDone());        //true
        System.out.println(f.isCancelled());   //false
        System.out.println(f.toString());      //FutureTask
        newModdedAgents.putAll(f.get());
    }catch(InterruptedException e)
    {
        System.out.println(f.isDone());        //true
        System.out.println(f.isCancelled());   //false
        System.err.println(e);                 //It is an interruptedException
        System.err.println(e.getCause());     //???? null?
        e.printStackTrace();
    }

输出

 Hola soy agente
 true
 false
 java.util.concurrent.FutureTask@1c4c94e5
 true
 false
 java.lang.InterruptedException
 null

java.lang.InterruptedException
at     java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1302)
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:248)
at java.util.concurrent.FutureTask.get(FutureTask.java:111)
at com.pf.simulator.Simulation.simulateStep(Simulation.java:217)
at com.pf.gui.ButtonPanel.doWork(ButtonPanel.java:141)
at com.pf.gui.ButtonPanel$1$1.construct(ButtonPanel.java:198)
at com.pf.gui.SwingWorker$2.run(SwingWorker.java:117)
at java.lang.Thread.run(Thread.java:636)

如果您想查看我将可调用内容汇总到线程池的位置...那么这将是它的代码

    for(Callable<HashMap<Integer, Agent>> c : agentCallables)
    {
        Future<HashMap<Integer,Agent>> future = pool.submit(c);
        agentFutureSet.add(future);
    }

然后我用

迭代这个Set
    for(Future<HashMap<Integer, Agent>> f : agentFutureSet)
    try
    {
              //Here goes the code at the beginning

4 个答案:

答案 0 :(得分:9)

在调用get()之前,您是否检查了线程的中断标志?您可以使用Thread.currentThread().isInterrupted()

执行此操作

有关更多信息,请查看Future.get()的javadoc,了解它为什么会抛出InterruptedException。

答案 1 :(得分:6)

InterruptedException抛出一个裸.get()表示当前执行线程(调用.get()的线程)在调用get()之前被中断,或者被阻塞在{ {1}}。这与与执行程序线程或其中一个任务被中断相同。某人或某事正在打断你的“主”线程 - 或者至少是调用.get()的线程。

中断不是随机发生的 - 某些代码必须故意造成中断。只能通过调用Thread.interrupt()来启动中断 ,但有一些标准的Java实用程序会在幕后调用它,例如Future.cancel(true)ExecutorService.shutdownNow()

AFAIK,无法从外部跟踪中断原因的“原因链”或“堆栈跟踪”。您必须查看源代码以确定可以启动中断的位置,从而推断出导致中断的方法调用。

答案 2 :(得分:1)

Exception的原因是Throwable(方法调用也不例外)

线程只会在你导致它的情况下被中断,它不会随机发生。

如果你真的不知道中断来自何处并且想要忽略它,你可以先清除它。致电Thread.interrupted()

答案 3 :(得分:0)

这表示执行提交的Callable的线程被中断。这可能是一个有意义的中断(例如,如果Callable执行一些阻塞操作,如Thread.sleep,并通过Thread.interrupt()明确中断),或者它可能是ExecutorService(假设您正在使用此功能)正在通过拨打shutDownNow()来关闭。

您能否发布用于创建线程池的代码以及Callable实现?