0

I'm reading JCP 7.2.4, it has the following code:

    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.

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.

My doubt is, if I replace this AtomicBoolean with volatile, what will be the potential risk? Any working thread could set it to true(when find mail), so is there chance I couldn't get correct value?

Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • 5
    Local variables can't be volatile, so the main risk with turning the AtomicBoolean into a volatile in this code is that it wouldn't compile anymore. :-) – yshavit Jun 18 '22 at 16:36

1 Answers1

3

Obviously not; local variables that are used in lambdas or inner classes must be effectively final. AtomicBoolean works because your variable is a reference to an object - and doesn't change.

Perhaps try it first before asking :)

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
rzwitserloot
  • 85,357
  • 5
  • 51
  • 72