-1

I tried to store my starting Thread in a ListArray but this results in ConcurrentModificationExeption. Can anybody help?

TimerTask timerTask = new TimerTask() {

        @Override
        public void run() {
            getData(parameters);

        }
    };
    ArrayList<TimerTask> threadList = Threads.getInstance();
    if(!threadList.isEmpty()){
        for (Iterator<TimerTask> it = threadList.iterator(); it.hasNext(); ) {
            TimerTask timerT = it.next();
            boolean found = false;
            if (timerTask.equals(timerT)){
                found = true;
            }
            if(!found){
                threadList.add(timerTask);
                Timer timer = new Timer();
                timer.scheduleAtFixedRate(timerTask, 0, 10000);
            }
        }
    }else{
        threadList.add(timerTask);
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(timerTask, 0, 10000);
    }
David
  • 6,462
  • 2
  • 25
  • 22
pumukel
  • 71
  • 9
  • The problem comes from the fact that you modify the list while iterating on it. If you wanted to remove elements, you could safely do it with `iterator.remove()` but I do not know a way to add elements safely while iterating on the list. Maybe you can make a list of elements to add then add them all at the end. – Arnaud Denoyelle Oct 23 '14 at 21:23
  • @ArnaudDenoyelle I think the op did not want to remove any elements. The op wants to add elements to a list – Kick Buttowski Oct 23 '14 at 21:26
  • what do you mean with duplicate? – pumukel Oct 23 '14 at 21:35
  • @pumukel It means that a similar question has already been asked. This user advises you to make a research in StackOverflow because you might have found your answer without having to create a new question. – Arnaud Denoyelle Oct 23 '14 at 21:38
  • why is it not possible to make it synchronized? like: public synchronized void – pumukel Oct 23 '14 at 21:38
  • @pumukel It is not a problem of multithreading. Hence, using `synchronized` would not solve the problem. Modifying a list while iterating on it is only doable with an iterator. – Arnaud Denoyelle Oct 23 '14 at 21:44
  • @pumukel Hence, either you use an iterator or you modify the list *after* iterating. – Arnaud Denoyelle Oct 23 '14 at 21:45

2 Answers2

1

You cannot add elements to an ArrayList while iterating on it (except if you do it via a ListIterator as stated by zapl).

for (Iterator<TimerTask> it = threadList.iterator(); it.hasNext(); ) {
  /* [..] */
  if(!found){
    threadList.add(timerTask); //Here is the problem
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(timerTask, 0, 10000);
  }
}

You should rather :

  • Use the ListIterator. (I advise you this one)
  • OR make a list of all elements to add then add them outside of the for loop.
Community
  • 1
  • 1
Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
  • 2
    or inside the loop using [`ListIterator#add`](http://stackoverflow.com/a/18995101/995891) – zapl Oct 23 '14 at 21:29
  • @ArnaudDenoyelle is array thread safe? because from the post that I got it suggested that – Kick Buttowski Oct 23 '14 at 21:32
  • @KickButtowski I do not know. ConcurrentModificationException is misleading : it has nothing to deal with thread safety here. – Arnaud Denoyelle Oct 23 '14 at 21:35
  • @ArnaudDenoyelle can you give me your opinion about my answer plz? – Kick Buttowski Oct 23 '14 at 21:36
  • @KickButtowski honestly, I do not like it. 1) it is bad to use an array for 'write' operations (not efficient and it is not possible to predict the final array's size). 2) Iterators are intended for this purpose so it would be better to use them. – Arnaud Denoyelle Oct 23 '14 at 21:42
0

To Avoid ConcurrentModificationException in multi-threaded environment:

1. You can convert the list to an array and then iterate on the array. This approach works well for small or medium size list but if the list is large then it will affect the performance a lot.

2. You can lock the list while iterating by putting it in a synchronized block. This approach is not recommended because it will cease the benefits of multithreading.

3. If you are using JDK1.5 or higher then you can use ConcurrentHashMap and CopyOnWriteArrayList classes. It is the recommended approach.

Suggestion: As number one suggested, add all elements in the temp array and copy the temp array into your list after the for loop.

Source that I used

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58