下面是 Brian Goetz 的 Java Concurrency in Practice 中清单 7.20 中的代码:
public class CheckForMail {
public boolean checkMail(Set<String> hosts, long timeout, TimeUnit unit)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final AtomicBoolean hasNewMail = new AtomicBoolean(false);
try {
for (final String host : hosts)
exec.execute(new Runnable() {
public void run() {
if (checkMail(host)) hasNewMail.set(true);
}
});
} finally {
exec.shutdown();
exec.awaitTermination(timeout, unit);
}
return hasNewMail.get();
}
private boolean checkMail(String host) { // Check for mail return
false;
}
}
在引用这段代码时,Goetz 说:"使用 AtomicBoolean 而不是易失布尔值的原因是,为了从内部 Runnable 访问 hasMail 标志,它必须是最终的,这将排除修改它"(第 158 页(。
为什么它必须是最终的?你不能让它成为一个非最终的布尔易失性吗?
但是,为什么它必须是最终的?你不能让它成为一个非最终的布尔易失性吗?
hasNewMail
需要从内部Runnable
访问,正如Goetz所说。 这是一个内部类的实例。 在最新版本的 Java 中,变量是"有效最终的"是内部类访问词法封闭方法的局部变量的要求。 我认为Goetz是在要求更强的时候写的:变量确实是final
的。 "有效最终"和final
之间的区别对于此目的并不重要,但是,无论哪种方式,变量都无法修改。
还要注意的是,Goetz 代码中的AtomicBoolean
是final
。 它本身不能修改,但存储在其中的值可以修改,这就是程序的工作方式。
局部变量不能是易失性的。如果您尝试进行该更改,您将看到这是一个编译错误。
顺便说一下,从Java 8开始,你不再需要将变量标记为final;只要它实际上是final的(也就是说,你没有在第一次之后设置它(,Java就会接受它,就好像你把它标记为final一样。