Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I get this exception when I start a second timer after canceling the first one.Both timers uses a separate ArrayList and iterates through it. No removal/modification is performed on the list, still I get concurrent modification exception when I stop the first timer and start the second one right away. If I wait few seconds before initiating the second timer, then it works fine.I ended up making a copy of the incoming list on both timers, passed the copy to the timer, still gets the error.Not sure why I get the error even though I am merely iterating through the list and writing the data to a flat file.

This is my code:

Timer 1

private void timerwork(final List<Object> list) throws IOException {
    timer = new Timer();
    final List<Object> taskList = list;
    timer.scheduleAtFixedRate(new CustomTimerTask(taskList) {

        @Override
        public void run() {

        if (taskList != null && !taskList.isEmpty()) {

        synchronized (taskList) {

            for (Object o: taskList) {

            try {
                valueIncrementOperation(o);// this method takes  each obect, 
                    does some logic and writes to a flat file, 
                    it does not modify the object itself, 
                    but just reads it and do some ext calculation 
                     on some local variables
            } catch (IOException e) {


            timer.cancel();
            timer.purge();
            throw new RuntimeException(e.getMessage(), e);
            }

        }
                //once exited out of the loop, 
                   it copies the flat file to another file
        try {


        copyFileUsingFileChannels(source, finaldest);

    } catch (IOException e) {
    }

}


public synchronized void valueIncrementOperation(Object o)
        throws IOException {

    DataInputStream d = new DataInputStream(new FileInputStream(sourcefile));

    DataOutputStream out = new DataOutputStream(new FileOutputStream(
            tempfile));


    initialValue = Long.parseLong(o.getDefaullt_value());

    String count;
    String t;
    while ((count = d.readLine()) != null) {
        String u = count.toUpperCase();
        String[] z = u.split(" ");

        if (z[0].contains(o.getO())) {

                       ............................
            out.writeBytes(t + "\n");

}

d.close();
out.close();

copyFileUsingFileChannels(source, initialDest);

}

CustomTimerTask code:

public class CustomTimerTask extends TimerTask {

private List<Object> list = new ArrayList<Object>();

public CustomTimerTask(List<Object> list) {

    this.list = list;
}

@Override
public void run() {
    // TODO Auto-generated method stub

}

Timer 2 has similar logic: ie, makes copy of incoming list before passing to timer2. Still I get this error:

Exception in thread "Timer-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)

Work around is to wait few seconds before starting timer2. Is there a better way to address this scenario?

share|improve this question
    
obvious question: what is at com.comcast.ams.simulator.service.OidTypesDao$2.run(OidTypesDao.java:307) ? (obvious answer : you are in a foreach loop in which you remove items from your list.) –  njzk2 Nov 29 '13 at 18:01
    
this.list = list; doesn't make a copy of the list, it just makes a new reference to the same list. –  DavidC Nov 29 '13 at 18:04
    
A simple solution would probably be to replace your List with a java.util.concurrent.CopyOnWriteArrayList. This will likely fix your problem. –  Gennaro De Luca Nov 29 '13 at 18:06
    
@DavidC - i am copying list even before calling the timer constructor final List<Object> taskList = list; and pass in taskList to constructor –  decent guy Nov 29 '13 at 18:07
    
change it to final List<Object> taskList = new ArrayList<Object>(list); to make a copy, or use a copy-on-write implementation as @Gennaro mentioned. –  DavidC Nov 29 '13 at 18:09
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.