4

次のコードでは、Callable実行結果に関するメッセージを何らかの UI スレッドに発行する必要があります。

Future<T> aFuture = aExecutorService.submit(aCallable); //suppose in thread A

aExecutorService.execute(new Runnable() { //suppose in thread B
                @Override
                public void run() {
                    try {
                        final T aresult = aFuture.get();
                        sendSuccessMesage(aResult);
                    }catch( . . . . . . e)
                      . . . . . . . 
                      sendExceptionHappenedMessage(e.getMessage());
                      . . . . . . .
                    }
                }

スレッド A が中断された場合、スレッド B は永遠に結果を待ち続けますか? これを行う代替/安全な方法は何ですか?

4

2 に答える 2

2

タスクaCallableがキャンセルされた場合、get() が戻らない可能性があります。これを行う最も安全で効率的な方法は、1 つのタスクを使用することです。

Future future = aExecutorService.submit(new Runnable() {
    @Override
    public void run() {
        try {
            final T aresult = aCallable.call();
            sendSuccessMesage(aResult);
        } catch(Throwable e)
            sendExceptionHappenedMessage(e.getMessage());
        }
    }
});

// to cancel.
future.cancel(true);

キャンセルする代わりに、AtomicBoolean を true に設定し、キャンセルされたかどうかを確認することもできます。このようにして、sendCancelledMessage必要な場合でも送信できます。

于 2012-10-02T08:51:31.430 に答える
0

スレッド A での割り込みの処理方法によって異なります。たとえば、次のようになります。

Future<T> aFuture = null;
try {
    aFuture = aExecutorService.submit(aCallable);
    Thread.sleep(FOREVER);
} catch (InterruptedException e) {
    if (aFuture != null) {
        aFuture.cancel(true); //true = interrupts
    }
}

その場合、aFuture.get()スレッド B は InterruptedException もスローしますが、これをキャッチできます。

于 2012-10-02T08:52:11.703 に答える