title: AtomicReference to a mutable object and visibility
body: <p>Say I have an <code>AtomicReference</code>to a list of objects:</p>
  
  <pre><code>AtomicReference&lt;List&lt;?&gt;&gt; batch = new AtomicReference&lt;List&lt;Object&gt;&gt;(new ArrayList&lt;Object&gt;());
  </code></pre>
  
  <p><strong>Thread A</strong> adds elements to this list: <code>batch.get().add(o);</code></p>
  
  <p>Later, <strong>thread B</strong> takes the list and, for example, stores it in a DB: <code>insertBatch(batch.get());</code></p>
  
  <p>Do I have to do additional synchronization when writing (Thread A) and reading (Thread B) to ensure thread B sees the list the way A left it, or is this taken care of by the AtomicReference?</p>
  
  <p>In other words: if I have an AtomicReference to a mutable object, and one thread changes that object, do other threads see this change immediately?</p>
  
  <p>Edit:</p>
  
  <p>Maybe some example code is in order:</p>
  
  <pre><code>public void process(Reader in) throws IOException {
      List&lt;Future&lt;AtomicReference&lt;List&lt;Object&gt;&gt;&gt;&gt; tasks = new ArrayList&lt;Future&lt;AtomicReference&lt;List&lt;Object&gt;&gt;&gt;&gt;();
      ExecutorService exec = Executors.newFixedThreadPool(4);
  
      for (int i = 0; i &lt; 4; ++i) {
          tasks.add(exec.submit(new Callable&lt;AtomicReference&lt;List&lt;Object&gt;&gt;&gt;() {
              @Override public AtomicReference&lt;List&lt;Object&gt;&gt; call() throws IOException {
  
                  final AtomicReference&lt;List&lt;Object&gt;&gt; batch = new AtomicReference&lt;List&lt;Object&gt;&gt;(new ArrayList&lt;Object&gt;(batchSize));
  
                  Processor.this.parser.parse(in, new Parser.Handler() {
                      @Override public void onNewObject(Object event) {
                              batch.get().add(event);
  
                              if (batch.get().size() &gt;= batchSize) {
                                  dao.insertBatch(batch.getAndSet(new ArrayList&lt;Object&gt;(batchSize)));
                              }
                      }
                  });
  
                  return batch;
              }
          }));
      }
  
      List&lt;Object&gt; remainingBatches = new ArrayList&lt;Object&gt;();
  
      for (Future&lt;AtomicReference&lt;List&lt;Object&gt;&gt;&gt; task : tasks) {
          try {
              AtomicReference&lt;List&lt;Object&gt;&gt; remainingBatch = task.get();
              remainingBatches.addAll(remainingBatch.get());
          } catch (ExecutionException e) {
              Throwable cause = e.getCause();
  
              if (cause instanceof IOException) {
                  throw (IOException)cause;
              }
  
              throw (RuntimeException)cause;
          }
      }
  
      // these haven't been flushed yet by the worker threads
      if (!remainingBatches.isEmpty()) {
          dao.insertBatch(remainingBatches);
      }
  }
  </code></pre>
  
  <p>What happens here is that I create four worker threads to parse some text (this is the <code>Reader in</code> parameter to the <code>process()</code> method). Each worker saves the lines it has parsed in a batch, and flushes the batch when it is full (<code>dao.insertBatch(batch.getAndSet(new ArrayList&lt;Object&gt;(batchSize)));</code>).</p>
  
  <p>Since the number of lines in the text isn't a multiple of the batch size, the last objects end up in a batch that isn't flushed, since it's not full. These remaining batches are therefore inserted by the main thread.</p>
  
  <p>I use <code>AtomicReference.getAndSet()</code> to replace the full batch with an empty one. It this program correct with regards to threading?</p>