Share this page 

Handle concurrent read/writeTag(s): Thread


Take the following program
import java.util.*;

public class RW {
 private static Vector data = new Vector();

 public static void main(String[] args) throws Exception {
  new Producer().start();
  new Consumer().start();
    }

 static class Consumer extends Thread {
  Consumer(){
   super("Consumer");
  }
  public void run(){
   for(;;){
    try {
     Thread.sleep(1);
     } 
    catch (Exception e){
     e.printStackTrace();
     }
     Iterator it = data.iterator();
     while (it.hasNext()) it.next();
    }
   }
  }
 
 static class Producer extends Thread {
  Producer(){
   super("Producer");
   }
  public void run(){
   for(;;){
    try {
     Thread.sleep(1);
     } 
    catch (Exception e){
     e.printStackTrace();
     }
    data.addElement(new Object());
    if (data.size() > 1000) data.removeAllElements();
    }
   }
 }
}
The following Exception is generated very quickly because the Producer is trying to modify the data (a Vector) while the Consumer is using it.
java.util.ConcurrentModificationException
       at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
       at java.util.AbstractList$Itr.next(Unknown Source)
       at RW$Consumer.run(RW.java:26)
The solution is to use the keyword synchronized to put a lock on the data while we are using it.
import java.util.*;

public class RW {
 private static Vector data = new Vector();

 public static void main(String[] args) throws Exception {
  new Producer().start();
  new Consumer().start();
    }

 static class Consumer extends Thread {
  Consumer(){
   super("Consumer");
  }
  public void run(){
   for(;;){
    try {
     Thread.sleep(1);
     } 
    catch (Exception e){
     e.printStackTrace();
     }
    synchronized(data){
     Iterator it = data.iterator();
     while (it.hasNext()) it.next();
     }
    }
   }
  }
 
 static class Producer extends Thread {
  Producer(){
   super("Producer");
   }
  public void run(){
   for(;;){
    try {
     Thread.sleep(1);
     } 
    catch (Exception e){
     e.printStackTrace();
     }
    data.addElement(new Object());
    if (data.size() > 1000) data.removeAllElements();
    }
   }
 }
}