为什么Goetz不再使用volatile boolean for Listing 7.20?

kat*_*ex7 0 java concurrency multithreading final atomicboolean

以下是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;
    }
}
Run Code Online (Sandbox Code Playgroud)

参考此代码,Goetz说"使用AtomicBoolean而不是volatile布尔值的原因是为了从内部Runnable访问hasMail标志,它必须是final,这将阻止修改它"(p.158 ).

为什么它必须是最终的?难道你不能让它成为一个非最终的布尔波动?

Joh*_*ger 6

但是为什么它必须是最终的?难道你不能让它成为一个非最终的布尔波动?

hasNewMail需要从内部访问Runnable,正如Goetz所说.那是一个内部类的实例.在最新版本的Java中,变量"有效最终"是内部类访问词法封闭方法的局部变量的要求.我认为Goetz在需求更强的时候写作:变量确实是final.然而,"有效最终"之间的区别final对于此目的并不重要,但无论如何,变量都无法修改.

请注意,AtomicBooleanGoetz的代码是final.它本身不能修改,但存储在其中的值可以,这就是程序的工作方式.

  • @ paulsm4,即Java语言架构师[Brian Goetz](http://www.oracle.com/us/technologies/java/briangoetzchief-188795.html).该列表来自他的书,[*Java Concurrency in Practice*](http://jcip.net/). (5认同)