質問

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 実装?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top