gpt4 book ai didi

java - 实现不抛出 InterruptedException 的接口(interface)时处理 InterruptedException 的正确方法

转载 作者:行者123 更新时间:2023-12-01 18:47:22 24 4
gpt4 key购买 nike

场景如下。

我实现了一个这样的界面:

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

此接口(interface)有两种实现:一种从静态源读取,这些静态源在“构造函数时”完全初始化,另一种则不读取;后一个实现如下( expiryEnabledAtomicBoolean ;注释已删除,完整源代码 heresourcesMap<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;
}
}

由于接口(interface)本身没有声明抛出InterruptedException (因为某些实现永远不会这样做),我这样做Thread.currentThread.interrupt() 。我这样做是为了符合界面。反过来,该接口(interface)的实现在“主”、面向用户的类中使用:

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可以扔掉。而且由于基接口(interface)没有声明抛出异常,所以如果我捕获一个异常,我会选择恢复线程中断状态。

然而,文献并不同意:它说,只有当您位于 Thread 范围内时,您才应该这样做,或者忽略异常。您自己创建的。

我的问题是:这是一个面向用户的 API,我目前处理此问题的方式是否存在潜在问题?如果是,我该如何解决?

最佳答案

Now, the problem is with the FutureTask. As .get() is blocking, an InterruptedException can be thrown. And since the base interface does not declare to throw the exception, if I catch one I choose to restore the thread interruption status.

这是完全正确的。您应该始终这样做。

try {
...
} catch (InterruptedException e) {
// InterruptedException clears interrupt flag
// I always re-interrupt the thread first
Thread.currentThread().interrupt();
// then i decide if I want the thread to return or throw or ...
return;
}

我还想说,您应该考虑一下您的线程被中断意味着什么。有人中断了正在调用 future.get() 的线程。该线程应该如何响应?

  • 它应该抛出RuntimeException吗?
  • 是否应该停止正在做的事情并退出?
  • 是否应该关闭线程池?

Literature, however, disagrees: it says that you should only do that, or ignore the exception, only in the event that you are within a Thread that you created yourself.

我不确定您正在查看哪些文献,但在我看来,它是不正确的或不精确的。

关于java - 实现不抛出 InterruptedException 的接口(interface)时处理 InterruptedException 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17199720/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com