Concurrent threads adding to ArrayList at same time - what happens?

后端 未结 9 1895
星月不相逢
星月不相逢 2020-11-28 05:28

We have multiple threads calling add(obj) on an ArrayList.

My theory is that when add is called concurrently by two threads,

9条回答
  •  执笔经年
    2020-11-28 06:08

    I came up with the following code to mimic somewhat a real world scenario.

    100 tasks are run in parallel and they update their completed status to the main program. I use a CountDownLatch to wait for task completion.

    import java.util.concurrent.*;
    import java.util.*;
    
    public class Runner {
    
        // Should be replaced with Collections.synchronizedList(new ArrayList())
        public List completed = new ArrayList();
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            Runner r = new Runner();
            ExecutorService exe = Executors.newFixedThreadPool(30);
            int tasks = 100;
            CountDownLatch latch = new CountDownLatch(tasks);
            for (int i = 0; i < tasks; i++) {
                exe.submit(r.new Task(i, latch));
            }
            try {
                latch.await();
                System.out.println("Summary:");
                System.out.println("Number of tasks completed: "
                        + r.completed.size());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            exe.shutdown();
        }
    
        class Task implements Runnable {
    
            private int id;
            private CountDownLatch latch;
    
            public Task(int id, CountDownLatch latch) {
                this.id = id;
                this.latch = latch;
            }
    
            public void run() {
                Random r = new Random();
                try {
                    Thread.sleep(r.nextInt(5000)); //Actual work of the task
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                completed.add(id);
                latch.countDown();
            }
        }
    }
    

    When i ran the application 10 times and at least 3 to 4 times the program did not print correct number of completed tasks. Ideally it should print 100(if no exceptions happen). But in some cases it was printing 98, 99 etc.

    Thus it proves that concurrent updates of ArrayList will not give correct results.

    If i replace the ArrayList with a Synchronized version, the program outputs the correct results.

提交回复
热议问题