简体   繁体   English

如果我在这段代码中用 volatile 替换 AtomicBoolean 会有什么风险?

[英]What's the risk if I replace AtomicBoolean with volatile in this code?

I'm reading JCP 7.2.4, it has the following code:我正在阅读 JCP 7.2.4,它具有以下代码:

    boolean checkMail(Set<String> hosts, long timeout, TimeUnit unit)
    throws InterruptedException
    {
        ExecutorService exec = Executors.newCachedThreadPool();
        final AtomicBoolean hasNewMail = new AtomicBoolean(false); // can we use volatile here?
        try{
            for(final String host : hosts){
                exec.execute(new Runnable() {
                    public void run(){
                        if(checkMain(host)){
                            hasNewMail.set(true);
                        }
                    }
                });
            }
        }finally{
            exec.shutdown();
            exec.awaitTermination(timeout, unit);
        }
        return hasNewMail.get();
    }

The book says: Atomic, not volatile, should be used, as the inner Runnable could visit hasNewMail .这本书说:应该使用原子的,而不是易失的,因为内部的Runnable可以访问hasNewMail

Boolean value is set to true when there's mail, without considering if its previous value is true of false, regardless whether other threads are setting its value.有邮件时布尔值设置为true,不考虑其前一个值是true还是false,不管其他线程是否在设置它的值。

My doubt is, if I replace this AtomicBoolean with volatile, what will be the potential risk?我的疑问是,如果我用 volatile 替换这个 AtomicBoolean,潜在的风险是什么? Any working thread could set it to true(when find mail), so is there chance I couldn't get correct value?任何工作线程都可以将其设置为 true(当找到邮件时),那么我是否有可能无法获得正确的值?

Obviously not;明显不是; local variables that are used in lambdas or inner classes must be effectively final .在 lambda 或内部类中使用的局部变量必须是有效的 final AtomicBoolean works because your variable is a reference to an object - and doesn't change. AtomicBoolean有效,因为您的变量是对对象的引用 - 并且不会改变。

Perhaps try it first before asking :)也许在询问之前先尝试一下:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM