Jxt*_*tps 7 java exception-handling thread-safety race-condition
许多Java资源使用示例如下所示:
Resource r = openResource();
try {
// use resource
} finally {
r.close();
}
Run Code Online (Sandbox Code Playgroud)
声明r必须在try-clause 之外才能在finally-clause中显示,但这也使得它看起来像是一个潜在的竞争条件:如果在openResource()-call和进入try-clause 之间存在线程中断怎么办?
这是否意味着在该场景中资源实际上并未关闭?
或者Java是否保证try-finally封面r"完全",尽管语法看起来不像?
或者我必须写:
Resource r = null;
try {
r = openResource();
// use resource
} finally {
if (r != null) r.close();
}
Run Code Online (Sandbox Code Playgroud)
为了防止线程中断?
如果在 openResource() 调用和进入 try 子句之间发生线程中断怎么办?
然后线程不会抛出异常,InterruptedException直到遇到一些阻塞调用。在进入try块之前这种情况不会发生,因为假设该方法实际返回,就不会再有任何阻塞调用。从文档中InterruptedException:
当线程正在等待、休眠或以其他方式占用,并且线程在活动之前或活动期间被中断时抛出。有时,一个方法可能希望测试当前线程是否已被中断,如果是,则立即抛出此异常。
请注意,即使您确实将获取放入try块内,这并不能真正防止任何本来存在的竞争条件 - 因为您将依赖于首先返回的方法或构造函数。如果异常可以在方法/构造函数返回之后发生,为什么它不能在返回之前发生,而是在获取资源之后发生?如果发生这种情况,你就没有什么可以打电话close的了...
我仍然建议在 Java 7 中使用 try-with-resources 语句,但是如果您查看JLS 第 14.20.3.1 节,您会发现扩展就像您的第一段代码:
基本 try-with-resources 语句的含义:
Run Code Online (Sandbox Code Playgroud)try ({VariableModifier} R Identifier = Expression ...) Block由以下对局部变量声明和 try-catch-finally 语句的翻译给出:
Run Code Online (Sandbox Code Playgroud){ final {VariableModifierNoFinal} R Identifier = Expression; Throwable #primaryExc = null; try ResourceSpecification_tail Block catch (Throwable #t) { ... #primaryExc = #t; throw #t; } finally { ... } }