title: Need Fool Proof Synchronization of ArrayList in A Multi-threaded Environment
body: <p>I've been at this for a week now doing my research on how to properly synchronize an ArrayList.</p>
  
  <p>My main issue in a nutshell is I have a "master" ArrayList of objects. Different threads may come in and add/set/remove from this list. I need to be sure that when one thread is iterating through the ArrayList, another is not changing it.</p>
  
  <p>Now I've read many articles on the "best" way of handling this:</p>
  
  <ul>
  <li>use collections.synchronizedlist</li>
  <li>use CopyOnWriteArrayList</li>
  <li>use synchronized() blocks in conjunction with collections.synchronizedlist</li>
  <li>use Vector (many people are against this)</li>
  </ul>
  
  <p>Using synchronized blocks around every iteration, add/set/remove block seems to be kind of what I want, but people have said there is a lot of overhead.</p>
  
  <p>So then I started playing with CopyOnWriteArrayList (I do way more reads than writes for my master ArrayList). This is fine for reading, but what a lot of forum threads neglect to mention is that elements cannote be added, set, or removed from the iterator itself. For example (a basic version, but imagine it in a multi-threaded environment):</p>
  
  <pre><code>public static void main(String[] args) {
  
      class TestObject{
          private String s = "";
          public TestObject(String s){
              this.s = s;
          }
  
          public void setTheString(String s){
              this.s = s;
          }
  
          public String getTheString(){
              return s;
          }
      }
  
      CopyOnWriteArrayList&lt;TestObject&gt; list = new CopyOnWriteArrayList&lt;TestObject&gt;();
      list.add(new TestObject("A"));
      list.add(new TestObject("B"));
      list.add(new TestObject("C"));
      list.add(new TestObject("D"));
      list.add(new TestObject("E"));
  
      ListIterator&lt;TestObject&gt; litr = list.listIterator();
  
      while(litr.hasNext()){
        TestObject test = litr.next();
        if(test.getTheString().equals("B")){
           litr.set(new TestObject("TEST"));
        }
      }
  }
  </code></pre>
  
  <p>the line "litr.set(new TestObject("TEST"));" would throw a</p>
  
  <pre><code>java.lang.UnsupportedOperationException
  </code></pre>
  
  <p>And looking at the Java Documentation there is a specific line describing this behavior:</p>
  
  <p>"Element-changing operations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException."</p>
  
  <p>So then you are forced to modify that list by using </p>
  
  <pre><code>list.set(litr.previousIndex(), new TestObject("TEST"));
  </code></pre>
  
  <p>Now technically shouldn't this present a synchronization issue? If another thread were to come in at the same time, and say, remove all elements from "list" the iterator would not see that, it would go to set the "list" at a given index and would throw an exception because the element at that point no longer exists. I just don't understand the point of CopyOnWriteArrayList if you cant add an element through the iterator itself. </p>
  
  <p>Am I missing the point with using CopyOnWriteArrayList?</p>
  
  <p>Do I wrap every iterator that ends up having to add/set/remove an element in a synchronized block?</p>
  
  <p>This HAS to be a common issue with multi-threading. I would have thought someone would have made a class that could handle all this without worry... </p>
  
  <p>Thanks in advance for having a look at this!</p>