7

我对 Java 中的 Future.get() 有一个奇怪的问题。它总是返回一个InterruptedException,但是奇怪的是异常的原因是null,所以我不知道是谁打断了我..

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

这是负责下面输出的代码。f 是 Future,并且可调用返回一个 HashMap ,其中 Agent 并不真正相关。抱歉,如果打印行太多,我只是想提供尽可能多的信息。callable 的 call 方法现在很简单System.out.println("Hola soy agente"),正如您将看到的,它被打印出来,这意味着 callable 也没有导致异常

这是代码:

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);
    }

然后我用

    for(Future<HashMap<Integer, Agent>> f : agentFutureSet)
    try
    {
              //Here goes the code at the beginning
4

4 回答 4

10

你在调用之前检查过线程的中断标志get()吗?您可以使用Thread.currentThread().isInterrupted().

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

于 2010-11-24T15:37:03.143 回答
6

一个bareInterruptedException被抛出.get()表示当前执行线程(线程调用.get())在调用之前被中断get(),或者在被阻塞时被中断.get()。这执行程序线程或其任务之一被中断不同。有人或某事正在中断你的“主”线程——或者至少是线程调用.get().

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

AFAIK,没有办法从外部跟踪中断原因的“原因链”或“堆栈跟踪”。您必须查看源代码以确定可以在何处启动中断,从而推断在您的情况下是什么方法调用导致了中断。

于 2010-11-24T16:20:26.397 回答
1

异常的原因是 Throwable(方法调用不是异常)

线程只有在你造成它时才会被中断,它不会随机发生。

如果你真的不知道中断来自哪里并想忽略它,你可以先清除它。称呼Thread.interrupted()

于 2010-11-24T15:37:13.783 回答
0

这表明执行提交的 Callable 的线程被中断。这可能是合法的中断(例如,如果Callable执行某些阻塞操作,例如 Thread.sleep 并通过 显式中断Thread.interrupt()),或者可能是ExecutorService(假设您正在使用它)正在通过调用shutDownNow().

您能否将用于创建线程池的代码与您的Callable实现一起发布?

于 2010-11-24T15:40:06.830 回答