以下是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而不是volatile布尔值的原因是为了从内部Runnable访问hasMail标志,它必须是final,这将排除修改它”( p.158)。
为什么 才能成为最终版?难道你不能让它成为一个非最终的布尔波动?
答案 0 :(得分:6)
正如Goetz所说,需要从内部但为什么 最终?难道你不能让它成为一个非最终的布尔波动?
hasNewMail
访问 Runnable
。这是内部类的一个实例。在最新版本的Java中,变量“有效最终”是内部类访问词法封闭方法的局部变量的要求。我认为Goetz在需求更强的时候写作:变量确实是final
。 “有效最终”和final
之间的区别对于此目的并不重要,但无论如何,变量都无法修改。
请注意,Goetz代码中的AtomicBoolean
为final
。它本身不能修改,但存储在中的值可以是,这就是程序的工作方式。
答案 1 :(得分:2)
局部变量不可能是易变的。如果您尝试进行更改,则会发现它是编译错误。
顺便提一下,从Java 8开始,您不再需要将变量标记为final;只要它是effectively final(也就是说,你没有在第一次之后设置它),Java就会接受它,就像你将它标记为最终一样。