为什么 Goetz 不再在代码清单 7.20 中使用 volatile boolean?
Why did Goetz not use volatile boolean for Listing 7.20 again?
这是 Brian Goetz 的 Java 并发实践:
中清单 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 说 "The reason an AtomicBoolean is used instead of a volatile boolean is that in order to access the hasMail flag from the inner Runnable, it would have to be final, which would preclude modifying it"(第 158 页)。
为什么 有 是最终的?你不能把它变成一个非最终的布尔值 volatile 吗?
局部变量不能是可变的。如果您尝试进行该更改,您会发现这是一个编译错误。
顺便说一下,从 Java 8 开始,您不再需要将变量标记为 final;只要它是 effectively final(也就是说,你在第一次之后没有设置它),Java 就会接受它,就像你将它标记为最终的一样。
However why does it have to be final? Couldn't you just make it a non final boolean volatile?
正如 Goetz 所说,hasNewMail
需要从内部 Runnable
访问。这是一个 内部 class 的实例。在 Java 的最新版本中,变量 "effectively final" 是内部 class 访问词法封闭方法的局部变量的要求。我认为 Goetz 是在要求更强的时候写作的:变量确实是 final
。 "effectively final" 和 final
之间的差异对于此目的并不重要,但是,无论哪种方式,都无法修改变量。
还要注意,Goetz 代码中的 AtomicBoolean
是 final
。它本身无法修改,但存储在中的值可以修改,这就是程序的工作原理。
这是 Brian Goetz 的 Java 并发实践:
中清单 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 说 "The reason an AtomicBoolean is used instead of a volatile boolean is that in order to access the hasMail flag from the inner Runnable, it would have to be final, which would preclude modifying it"(第 158 页)。
为什么 有 是最终的?你不能把它变成一个非最终的布尔值 volatile 吗?
局部变量不能是可变的。如果您尝试进行该更改,您会发现这是一个编译错误。
顺便说一下,从 Java 8 开始,您不再需要将变量标记为 final;只要它是 effectively final(也就是说,你在第一次之后没有设置它),Java 就会接受它,就像你将它标记为最终的一样。
正如 Goetz 所说,However why does it have to be final? Couldn't you just make it a non final boolean volatile?
hasNewMail
需要从内部 Runnable
访问。这是一个 内部 class 的实例。在 Java 的最新版本中,变量 "effectively final" 是内部 class 访问词法封闭方法的局部变量的要求。我认为 Goetz 是在要求更强的时候写作的:变量确实是 final
。 "effectively final" 和 final
之间的差异对于此目的并不重要,但是,无论哪种方式,都无法修改变量。
还要注意,Goetz 代码中的 AtomicBoolean
是 final
。它本身无法修改,但存储在中的值可以修改,这就是程序的工作原理。