0

私はJavaで未来とマルチスレッドを初めて使用しています。複雑であることが判明した単純な問題があります。無限に開いている多数のスレッド (すべてに開いているセッションがあります) があります。1 つのスレッドがカスタム例外 (セッションでのタイムアウト例外) をスローするたびに、すべてのスレッドを中断し、すべてのセッションを適切に閉じる必要があります。私がしていることは、スレッドから返された将来のオブジェクトを (ArrayList に) 格納し、それをループ処理して、1 つのスレッドが例外をスローしたときにすべてに対して future.cancel を発行することです。

private static void futureCancel()
{
        for(int i=0;i<numberStreams;i++)
        {
            Future<String> future=futureList.get(i);
            try{
                future.cancel(true);
                future.get();
            }
            catch(InterruptedException e)
            {
                System.out.println("In interrupted block!");
            } catch (ExecutionException e) {
                e.printStackTrace();
            }       
        }
        return;
    }

ここでの問題は、いくつかの要件の問題と、セッションの反対側での動作方法が原因で、スレッド コードに InterruptedException を追加できないことです。callable から InterruptedException をスローすると、上記で指定した catch ブロックに到達しません。スレッドにスリープを追加して (テストには問題ありません)、InterruptedException を処理すると、future.cancel が発行されるとすぐにそのブロックに入ります。私は何を間違っていますか?

4

2 に答える 2

2

Futuer#cancel(boolean)javadoc状態

タスクが既に完了している、キャンセルされている、または他の理由でキャンセルできなかった場合、この試行は失敗します。成功し、キャンセルが呼び出されたときにこのタスクが開始されていない場合、このタスクは決して実行されません。タスクがすでに開始されている場合、mayInterruptIfRunning パラメータは、タスクを停止するために、このタスクを実行しているスレッドを中断する必要があるかどうかを決定します。

したがって、 /ExecutorServiceが実行されておらず、キューから削除できるか、 /が呼び出され、/コードがそれを処理する必要があります。RunnableCallableExecutorServiceThread#interrupt()RunnableCallable

Futureインターフェイスを介してスレッドを中断する他の方法はありません。Runnable割り込みを処理する方法がない場合、多くのことが発生する可能性があります。がInterruptedException発生すると、 にバブルアップし、からスローされるExecutorServiceにラップされます。を実行しているスレッドでno が発生した場合は、妨げられずに続行します。ExecutionExceptionFuture#get()InterruptedExceptionRunnableRunnable

Runnable割り込みを処理するように変更することを本当に検討する必要があります。

于 2014-02-05T19:46:47.073 に答える