Search code examples
javajava-8java.util.concurrentatomicinteger

Is ordered execution expected on the single thread


Since the service is single threaded, the monkey1 loop series will always get executed before monkey2, so we can expect monkey1 will always be greater than monkey2, can't we?

import java.util.concurrent.*;

public class MonkeyCounter {
    private static AtomicInteger monkey1 = new AtomicInteger(0); 
    private static AtomicLong monkey2 = new AtomicLong(0);

    public static void main(String[] args) {
      ExecutorService service = null;
      try {
        service = Executors.newSingleThreadExecutor(); 

        for(int i=0; i<100; i++)
        service.submit(() -> monkey1.getAndIncrement()); 
        for(int i=0; i<100; i++)
        service.submit(() -> monkey2.incrementAndGet());
        System.out.println(monkey1+" "+monkey2); 
      } finally {
       if(service != null) service.shutdown();
      }
    }
}

Solution

  • Javadoc on Executors.newSingleThreadExecutor:

    Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.

    Tasks are placed in a queue. Queue are FIFO so with single thread, the monkey1 > monkey2 is guaranteed if none of the increment fails.

    Bear in mind that value of monkey1 and monkey2 are undetermined because you do not wait for the jobs completion.