Future.get()は、中断されたExceptionで常に中断されます
-
28-09-2019 - |
質問
JavaのFuture.get()に奇妙な問題があります。それは常に中断されたエクセプトで戻ってきますが、奇妙なことは例外の原因がnullであるということですので、私は誰が私を中断したかわかりません。
get()を呼び出す前にチェックするのでさらに悪化し、ジョブの将来はすでに行われています。
以下に、以下の出力を担当するコードです。 Fは未来です, 、そして呼び出し可能なものは、エージェントが実際には関係のないハッシュマップを返します。申し訳ありませんが、プリントラインが多すぎる場合は、できる限りマッシュ情報を提供しようとしています。 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);
}
その後、私はこのセットを繰り返します
for(Future<HashMap<Integer, Agent>> f : agentFutureSet)
try
{
//Here goes the code at the beginning
解決
呼び出す前にスレッドの割り込みフラグを確認しましたか get()
?これを行うことができます Thread.currentThread().isInterrupted()
.
詳細については、Javadocをご覧ください future.get() それが中断されたエクセプトを投げる理由を見るために。
他のヒント
裸 InterruptedException
投げられる .get()
実行の現在のスレッド(スレッド呼び出しのスレッドが .get()
)呼び出す前に中断されました get()
, 、またはブロックされている間 .get()
. 。これは いいえ 執行者のスレッドまたはそのタスクの1つが中断されるのと同じことです。誰かまたは何かがあなたの「メイン」スレッド、または少なくともスレッド呼び出しを中断しています .get()
.
中断はランダムに発生しません - 一部のコードは意図的に中断を引き起こす必要があります。割り込み缶 それだけ 通話によって開始されます Thread.interrupt()
, 、しかし、これを舞台裏で呼ぶ標準的なJavaユーティリティがいくつかあります。 Future.cancel(true)
と ExecutorService.shutdownNow()
.
AFAIK、中断の原因の「原因チェーン」または「スタックトレース」を外部的に追跡する方法はありません。ソースコードを検討して、中断を開始できる場所を決定する必要があります。したがって、コールがどのメソッドがケースの中断を引き起こしているかを推測する必要があります。
例外の原因はスロー可能です(メソッド呼び出しは例外ではありません)
スレッドは、あなたがそれを引き起こす場合にのみ突破されます、それはランダムに起こりません。
割り込みがどこから来ているのかわからず、それを無視したい場合は、最初にクリアすることができます。電話 Thread.interrupted()
これは、提出された呼び出し可能な中断が中断されるスレッドを実行することを示しています。これは法定の中断かもしれません(たとえば Callable
swree.sleepなどのブロッキング操作を実行し、明示的に中断されます Thread.interrupt()
)、またはそれはそうかもしれません ExecutorService
(これを使用していると仮定)は、 shutDownNow()
.
スレッドプールを作成するために使用されるコードを投稿してください。 Callable
実装?