Screen flickering when running Particle system

please format code with </> button * homework policy * asking questions

I was coding a particle system that spews out fountains. I have been working to make the program more efficient, but now it starts flickering when the FPS slows down. I’m not sure if it’s linked to the FPS or the number of particles or the multithreading. Please let me know what might be causing this problem and what to fix.

Also, if you have any ideas on how to make my code more efficient, please let me know!

ArrayList <Fountain> fountains;

int velocityInitial;
double acceleration;
float spread = 22.5;

void setup() { // best speed: 45.873695 fps with 717,559 particles. What!? I got ~46 fps with 717 thousand(!) particles!
  fullScreen(); 
  //size(1920, 1080);
  // runs on the CPU so it's faster than GPU. This is because I've set it up to automatically multithread and CPU threads are faster than GPU ones, even if they are less numerous. halves processing time
  //note: this is still way faster even if I don't manually multithread. 
  velocityInitial = 2;
  acceleration = 0.001;
  fountains = new ArrayList();
  
  color x1 = color(255, 0, 0), x2 = color(0, 255, 0), y1 = color(255, 0, 0), y2 = color(0, 0, 255);
  
  int numCols = 16;
  int numRows = 4;
  loadPixels();
  for (int y = 0; y < numRows; y++) {
    for (int x = 0; x < numCols; x++) {
      float xRatio = ((x+0.5)/numCols);
      float yRatio = ((y+0.5)/numRows);
      color xcolor = lerpColor(x1, x2, xRatio);
      color ycolor = lerpColor(y1, y2, yRatio);
      color xycolor = lerpColor(xcolor, ycolor, 0.5);
      fountains.add(new Fountain(int(xRatio*width), int(yRatio*height), xycolor));
      fountains.get(fountains.size()-1).start();
    }
  }
  updatePixels();
  frameRate(120);
}

void draw() {
  background(0);

  loadPixels();
  for (int i = fountains.size() - 1; i >= 0; i--) {
    fountains.get(i).run();
  }
  
  updatePixels();

  keyCode = 0;
  if (frameCount % 1000 == 0) {
    int totalParticles = 0;
    for(Fountain f : fountains) {
      totalParticles += f.particles.size();
    }
    println(frameCount, frameRate, totalParticles);
  }
}


```class Fountain extends Thread{ // multithreading on CPU is fasterd
  int x, y;
  color pCol;
  boolean off = false;
  ArrayList <Particle> particles;
  
  Fountain(int _x, int _y, color _pCol) {
    super();
    x = _x;
    y = _y;
    pCol = _pCol;
    particles = new ArrayList<Particle>();
  }
  
  void run() {
    for(int i = 0; i < 10; i++) {
      particles.add(new Particle(x, y, pCol));
    }
    
    stroke(pCol);
    for(int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      if(p.done) {
        particles.remove(i);
        continue;
      }
      p.update();
    }
  }
}


class Particle {
  //PVector position, velocity;
  color col;
  double x, y, vx, vy;
  boolean done;
  
  Particle(int _x, int _y, color _c) {
    x = _x;
    y = _y;
    col = _c;
    
    float heading = PI*((randomGaussian()/3)*spread + 270)/180;
    float vi = abs(randomGaussian()/3)*velocityInitial + 0.5;
    vx = cos(heading)*vi;
    vy = sin(heading)*vi;
    done = false;
  }
  
  void update() {
    //move
    vy += acceleration;
    x += vx;
    y += vy;
    
    if (x < 0 || x > width || y > height || y < 0) {
      done = true;
      return;
    }
    
    //display
    pixels[(int)x + (int)y*width] = col; // way faster than using point function - gets nearly double 
  }
  
}

Another threading approach for Processing is double-buffer PGraphics or PImage: :thread: