为什么 Goetz 在清单 7.20 中没有再次使用易失性布尔值



下面是 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 代码中的AtomicBooleanfinal 。 它本身不能修改,但存储在其中的值可以修改,这就是程序的工作方式。

局部变量不能是易失性的。如果您尝试进行该更改,您将看到这是一个编译错误。

顺便说一下,从Java 8开始,你不再需要将变量标记为final;只要它实际上是final的(也就是说,你没有在第一次之后设置它(,Java就会接受它,就好像你把它标记为final一样。

相关内容

最新更新