Future.get()总是被InterruptedException中断

dgr*_*des 6 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();
    }
Run Code Online (Sandbox Code Playgroud)

和输出

 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)
Run Code Online (Sandbox Code Playgroud)

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

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

然后我迭代这个Set

    for(Future<HashMap<Integer, Agent>> f : agentFutureSet)
    try
    {
              //Here goes the code at the beginning
Run Code Online (Sandbox Code Playgroud)

dav*_*veb 9

你在调用之前检查了线程的中断标志get()吗?你可以这样做Thread.currentThread().isInterrupted().

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

  • 您可以通过查看 Future 的 javadoc 来了解原因,此处:http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html#get%28%29抛出“InterruptedException”“如果当前线程在等待时被中断” (2认同)
  • 令人难以置信的是,我在发帖之前多次访问该页面,但不知怎的,我的大脑就是没有想到等待的线程就是这个!有趣的是,因为其他人也有同样的误解,这次我在仔细阅读文档后向他们解释了同样的事情。第一次在 stackoverflow 发帖是一次非常有趣的经历! (2认同)

Mik*_*ark 6

InterruptedException抛出的裸露.get()表示当前执行线程(线程调用.get())在调用之前get()或被阻塞时被中断.get().这是相同的事,作为一个执行线程或者其任务之一被打断.某人或某事正在打断你的"主"线程 - 或者至少是线程调用.get().

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

AFAIK,没有办法从外部跟踪中断原因的"原因链"或"堆栈跟踪".您必须查看源代码以确定可以启动中断的位置,从而推断出在您的情况下导致中断的方法调用.