java Future.get() 总是被 InterruptedException 中断
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4268457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Future.get() gets interrupted always with an InterruptedException
提问by dgrandes
I have a WEIRD problem with Future.get() in Java. It returns always with an InterruptedException, however the weird thing is that the cause of the Exception is null, so I cant tell who interrupted me..
我在 Java 中使用 Future.get() 有一个奇怪的问题。它总是返回一个 InterruptedException,但奇怪的是异常的原因是空的,所以我不知道是谁打断了我。
It gets even worse because I check before calling get(), and the job Future has to do is already done.
情况变得更糟,因为我在调用 get() 之前进行了检查,而 Future 必须做的工作已经完成。
Here is the code responsible for the output below. f is the Future, and the callable returns a HashMap where Agent is not really relevant. Sorry if there are too many printlines, I'm just trying to give as mush info as I can. The call method from callable is for now a simple System.out.println("Hola soy agente")
that as you will see, gets printed, meaning that the callable didn't cause the exception either
下面是负责输出的代码。f 是 Future,并且可调用返回一个 HashMap ,其中 Agent 并不真正相关。抱歉,如果打印行太多,我只是想提供尽可能多的信息。callable 中的 call 方法现在很简单System.out.println("Hola soy agente")
,正如您将看到的,它会被打印出来,这意味着 callable 也不会导致异常
Here is the code:
这是代码:
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();
}
And the output
和输出
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.construct(ButtonPanel.java:198)
at com.pf.gui.SwingWorker.run(SwingWorker.java:117)
at java.lang.Thread.run(Thread.java:636)
In case you want to see where I sumbit the callable to the threadpool... then this would be the code for it
如果您想查看我在哪里将可调用对象添加到线程池中......那么这将是它的代码
for(Callable<HashMap<Integer, Agent>> c : agentCallables)
{
Future<HashMap<Integer,Agent>> future = pool.submit(c);
agentFutureSet.add(future);
}
and afterwards I iterate over this Set with
然后我迭代这个 Set
for(Future<HashMap<Integer, Agent>> f : agentFutureSet)
try
{
//Here goes the code at the beginning
回答by daveb
Did you check the thread's interrupt flag before calling get()
? You can do this with Thread.currentThread().isInterrupted()
.
在调用之前是否检查了线程的中断标志get()
?您可以使用Thread.currentThread().isInterrupted()
.
For more info look at the javadoc for Future.get()to see why it would throw an InterruptedException.
有关更多信息,请查看Future.get()的 javadoc以了解它为什么会抛出 InterruptedException。
回答by Mike Clark
A bare InterruptedException
being thrown from .get()
indicates that the current thread of execution (the thread calling .get()
) was interrupted before calling get()
, or while blocked in .get()
. This is notthe same thing as an executor thread or one of its tasks being interrupted. Someone or something is interrupting your "main" thread -- or at least the thread calling .get()
.
一个bare InterruptedException
is throw from.get()
表示当前执行线程(线程调用.get()
)在调用之前被中断get()
,或者在被阻塞时被中断.get()
。这是不相同的事,作为一个执行线程或者其任务之一被打断。某人或某事正在中断您的“主”线程——或者至少是线程调用.get()
.
Interruptions do not happen randomly -- some code has to intentionally cause the interruption. An interrupt can onlybe initiated by a call to Thread.interrupt()
, but there are a few standard Java utilities that call this behind the scenes, like Future.cancel(true)
and ExecutorService.shutdownNow()
.
中断不是随机发生的——某些代码必须故意引起中断。中断只能通过调用 来启动Thread.interrupt()
,但有一些标准的 Java 实用程序会在幕后调用它,例如Future.cancel(true)
和ExecutorService.shutdownNow()
。
AFAIK, there is no way of externally tracking the "cause chain" or "stack trace" of the cause of interruption. You must look to the source code to determine where interruptions can be initiated, and thus deduce what method call(s) are causing the interruption in your case.
AFAIK,没有办法从外部跟踪中断原因的“原因链”或“堆栈跟踪”。您必须查看源代码以确定可以在何处启动中断,从而推断出在您的情况下导致中断的方法调用。
回答by Peter Lawrey
The cause of an Exception is a Throwable (a method call is not an exception)
异常的原因是一个 Throwable(方法调用不是异常)
The thread will only be intrrupted if you cause it to be, it won't happen randomly.
线程只会在您导致它被中断时才会被中断,它不会随机发生。
If you really have no idea where the interrupt is coming from and want to ignore it you can clear it first. call Thread.interrupted()
如果您真的不知道中断来自哪里并想忽略它,您可以先清除它。称呼Thread.interrupted()
回答by Adamski
This is indicative of the thread executing the submitted Callable becoming interrupted. This could be a legimate interruption (for example if the Callable
performs some blocking operation such as Thread.sleep and is interrupted explicitly via Thread.interrupt()
), or it could be that the ExecutorService
(assuming you're using this) is being shut down via a call to shutDownNow()
.
这表明执行提交的 Callable 的线程被中断。这可能是合法的中断(例如,如果Callable
执行某些阻塞操作,例如 Thread.sleep 并通过 显式中断Thread.interrupt()
),或者可能是ExecutorService
(假设您正在使用它)正在通过调用关闭shutDownNow()
。
Can you please post the code used to create your thread pool along with your Callable
implementation?
您能否将用于创建线程池的代码与您的Callable
实现一起发布?