ArrayDeque iterator throws "Concurrent Modification Exception"

I’m sending values from another application (Pure Data) to Processing via OSC. That data is then visualized in Processing by scrolling by bars like a waveform using an ArrayDeque. It seems to run fine, except after a few minutes running I’m getting ConcurrentModificationException suggesting that I access data somwhere whil it is being deleted or written to. That’s surprising to me as it sounds like I’m running a threaded program, something I’m not aware of.
I’ve tried to remedy that by not drawing (and though accessing the first and last two items of the deque (for (int i = 2; i < width-2; i++)) but that did not help. As another try, I set up a blocking boolean while the OSC data is incoming, so that while the deque is written the read access is paused (boolean block_drawing). That also did not change the fact that I’m getting the ConcurrentModificationException error after a while.
Anyone has an idea what else to try?

import java.util.Queue;
import java.util.ArrayDeque;
import java.util.Iterator;
import oscP5.*;
import netP5.*;
OscP5 oscP5;

float WAVELEVEL = 0;
Queue<Integer> waveform = new ArrayDeque<Integer>();
boolean block_drawing = false;

void setup() {
  size(640, 360);
  oscP5 = new OscP5(this,12000);
  for (int i=0; i<width; i++) {
    waveform.add(int(0));
  }
}

void draw() {
    background(255);
    if (block_drawing == false){
      draw_waveform();
    }
    circle(mouseX,mouseY,20);
}

void oscEvent(OscMessage theOscMessage) {
  if(theOscMessage.checkAddrPattern("/wavelevel")==true) {
    if(theOscMessage.checkTypetag("f")) {
       float wavelevel = theOscMessage.get(0).floatValue();
       WAVELEVEL = wavelevel;
       block_drawing = true;
       waveform.remove();
       waveform.add(int(WAVELEVEL*(height/2)));
       block_drawing = false;
       return;
    }
  }
}

void draw_waveform(){
  pushMatrix();
  translate(0,height/2);
  Iterator<Integer> it = waveform.iterator();
  for (int i = 2; i < width-2; i++) {
    strokeWeight(2);
    stroke(50);
    int wave = it.next();
    line(i, wave, i, -wave);
  }
  popMatrix();
}

Do you

maybe try looping backwards

What does this line do?

Looping backwards will scroll my waveform from left to right… not ideal visually.

remove() Retrieves and removes the head of the queue represented by this deque.
See: ArrayDeque (Java Platform SE 7 )

I found a “solution” on this page Iterate through Queue in Java – Techie Delight
And modified my code as such:

import java.util.ConcurrentModificationException;
import java.util.Queue;
import java.util.ArrayDeque;
import java.util.Iterator;
import oscP5.*;
import netP5.*;
OscP5 oscP5;

float WAVELEVEL = 0;
Queue<Integer> waveform = new ArrayDeque<Integer>();
boolean block_drawing = false;

void setup() {
  //frameRate(50);
  size(640, 360);
  oscP5 = new OscP5(this,12000);
  for (int i=0; i<width; i++) {
    waveform.add(int(0));
  }
}

void draw() {
    background(255);
    if (block_drawing == false){
      draw_waveform();
    }
    circle(mouseX,mouseY,20);
}

void oscEvent(OscMessage theOscMessage) {
  if(theOscMessage.checkAddrPattern("/wavelevel")==true) {
    if(theOscMessage.checkTypetag("f")) {
       float wavelevel = theOscMessage.get(0).floatValue();
       WAVELEVEL = wavelevel;
       block_drawing = true;
       waveform.remove();
       waveform.add(int(WAVELEVEL*(height/2)));
       block_drawing = false;
       return;
    }
  }
}

void draw_waveform(){
  pushMatrix();
  translate(0,height/2);
  try{
    Iterator<Integer> it = waveform.iterator();
    int i = 0;
    while (it.hasNext()){
      strokeWeight(2);
      stroke(50);
      int wave = it.next();
      line(i, wave, i, -wave);
      i++;
    }
  }
   catch (ConcurrentModificationException ex) {
            System.out.println(ex);
   }
  popMatrix();
}

It’s not particularly beautiful, in essence I just catch the error and ignore it, so the program can go on. Solves my issue for the moment but I gladly accept a real solution.

1 Like

The rendering is not 100% smooth, there is a slight stutter. It’s not very strong, but noticeable. I am wondering if there is a way to make sure it is always smooth. I’m thinking of rendering it as a texture and then moving the object it is rendered on smoothly… or something like that. I also wonder how to have more parameters, like for example changing the color of the waveform for each bar. How to get more parameters/dimensions into the ArrayDeque?