0

シナリオは次のとおりです。

次のようなインターフェースを実装します。

public interface MessageSourceProvider
{
    MessageSource getMessageSource(Locale locale);
}

このインターフェースには 2 つの実装があります。1 つは「コンストラクター時」に完全に初期化される静的ソースから読み取るもので、もう 1 つはそうしないものです。この後者の実装は次のようになります (expiryEnabledAtomicBoolean; コメントは削除され、完全なソースはこちら;sourcesMap<Locale, FutureTask<MessageSource>>):

@Override
public MessageSource getMessageSource(final Locale locale)
{
    if (!expiryEnabled.getAndSet(true))
        setupExpiry(expiryDuration, expiryUnit);

    FutureTask<MessageSource> task;

    synchronized (sources) {
        task = sources.get(locale);
        if (task == null || task.isCancelled()) {
            task = loadingTask(locale);
            sources.put(locale, task);
            service.execute(task);
        }
    }

    try {
        final MessageSource source = task.get(timeoutDuration, timeoutUnit);
        return source == null ? defaultSource : source;
    } catch (InterruptedException ignored) {
        Thread.currentThread().interrupt(); // <-- HERE
        return defaultSource;
    } catch (ExecutionException ignored) {
        return defaultSource;
    } catch (TimeoutException ignored) {
        task.cancel(true);
        return defaultSource;
    } catch (CancellationException ignored) {
        return defaultSource;
    }
}

インターフェース自体はスローすることを宣言していないためInterruptedException(一部の実装では決してスローしないため)、私はThread.currentThread.interrupt(). これは、インターフェイスに準拠するためです。次に、このインターフェイスの実装は、「メイン」のユーザー向けクラスでそのまま使用されます。

public String getMessage(final Locale locale, final String key)
{
    BUNDLE.checkNotNull(key, "query.nullKey");
    BUNDLE.checkNotNull(locale, "query.nullLocale");

    String ret;
    MessageSource source;

    for (final Locale l: LocaleUtils.getApplicable(locale))
        for (final MessageSourceProvider provider: providers) {
            source = provider.getMessageSource(l);
            if (source == null)
                continue;
            ret = source.getKey(key);
            if (ret != null)
                return ret;
        }

    // No source found which has the key... Return the key itself.
    return key;
}

さて、問題はFutureTask. .get()ブロッキングと同様に、InterruptedExceptionをスローできます。また、基本インターフェイスは例外をスローすることを宣言していないため、例外をキャッチした場合は、スレッドの中断ステータスを復元することを選択します。

Threadしかし、文献は同意していません。自分で作成した の中にいる場合にのみ、それを行うか、例外を無視する必要があると書かれています。

私の質問は次のとおりです。これはユーザー向けの API ですが、現在これを処理している方法に潜在的な問題はありますか? はいの場合、どうすれば修正できますか?

4

2 に答える 2