Thread function in class

Hey I want to call a public function in a public class in the same class in processing (JAVA mode).

The Error:

Here is the complete code:

ParticleSystem ps;

PImage imageShape;

float deltaTime = 0;

void setup() {
  //fullScreen();
  size(600, 600);
  //(float x, float y, float tx, float ty, float s, color c_
  imageShape = loadImage(sketchPath("img.jpg"));
  imageShape.resize(100, 100);

  ps = new ParticleSystem(imageShape, width/2, height/2, 30);
}
void draw() {
  deltaTime = 1 / frameRate;
  background(0);
  ps.update();
}
class Particle {
  PVector pos;
  PVector target;
  float maxSpeed = 500;
  float dist;
  float size;
  color c;
  Particle(PVector p, PVector t, float s, color c_) {
    pos = p.copy();
    target = t.copy();
    size = s;
    c = c_;

    dist = PVector.dist(pos, target);
  }
  void show() {
    fill(c);
    noStroke();
    ellipse(pos.x, pos.y, size, size);
  }
  void move() {
    float currentDist = PVector.dist(pos, target);
    float speed = map(currentDist, 0, dist, 0, maxSpeed);
    PVector vel = PVector.sub(target, pos);
    vel.normalize();
    vel.mult(speed);
    vel.mult(deltaTime);
    pos.add(vel);
  }
}
class ParticleSystem {
  ArrayList<Particle> particles;
  PImage image;
  PVector startPos;
  float particleSize = 30;
  int count;
  ParticleSystem(PImage img, float x, float y, int c) {
    super();
    particles = new ArrayList<Particle>();
    image = img.copy();
    startPos = new PVector(x, y);
    count = c;
    thread("spawnParticles");
  }
  public void spawnParticles() {
    image.loadPixels();
    for (int i = 0; i < image.width; i++) {
      for (int j = 0; j < image.height; j++) {
        int index = i + j * image.width;
        color c = image.pixels[index];
        if (brightness(c) <= 40) {

          PVector targetPos = new PVector(map(i, 0, image.width, 0, width), map(j, 0, image.height, 0, height));
          Particle p = new Particle(startPos, targetPos, particleSize, color(255));
          particles.add(p);
          delay(50);
        }
      }
    }
    image.updatePixels();
  }
  void update() {
    for (Particle p : particles) {
      p.show();
      p.move();
    }
  }
}

Something that I’m noticing is that spawnParticles() is an instance method of the class. This means you need an initialized ParticleSystem object to run the method. In this case, I would suggest having the ParticleSystem class implement the Runnable interface so you can create a Thread object with it. You can do this by:

  1. Defining a public void method run() in the Runnable class, in this case, the ParticleSystem class. For you, this method would just call spawnParticles().
  2. Creating a Thread object: Thread myThread = new Thread(ps); Where ps is an instance of ParticleSystem.
  3. Running the thread using myThread.start();

This should accomplish what you want, and it’s not too much extra work to add.

Further reading about threads and multithreading:

Using more than one thread is good when you have a lot of concurrent and computationally intensive tasks. But, your single extra thread is just used to iterate over a 2D array of pixels. This won’t be much faster than just doing that on the main thread (if speed is your goal). Instead, it could be better to create a thread for every pixel that you iterate over to increase concurrency, the ability for code to be run at the same time. Even after doing this, threads will only be faster if the processing you have to do to initialize each particle is taxing. This is because it takes some time to schedule and manage threads behind the scenes. While I can’t see a lot of your spawnParticles() method, I’ll attempt to make it multithreaded. This multithreaded solution is separate from the previous solution I mentioned.

public class ParticleCreator implements Runnable {
  PImage img; // no need to pass image.copy(), this is just a reference. Also, this will override the global img variable if it is global.
  int tx, ty;
  public ParticleCreator(int tx_, int ty_, PImage image) {
    img = image;
    tx = tx_;
    ty = ty_;
  }
  
  public void run() {
    PVector targetPos = new PVector(map(tx, 0, img.width, 0, width), map(ty, 0, img.height, 0, height));
    Particle p = new Particle(startPos, targetPos, particleSize, color(255));
    // needed to ensure items are all added to the ArrayList properly
    synchronized(particles) {
      particles.add(p);
    }
  }
}

public void spawnParticles() {
  ArrayList<Thread> threads = new ArrayList<Thread>();
  image.loadPixels();
  for (int i = 0; i < image.width; i++) {
    for(int j = 0; j < image.height; j++) {
      int index = i + j * image.width;
      color c = image.pixels[index];
      if(brightness(c) <= 40) {
        Thread pc = new Thread(new ParticleCreator(i, j));
        threads.add(pc);
        pc.start();
      }
    }
  }
  for (Thread t : threads) {
    t.join(); //ensures that all the threads finish processing before the method ends. This will cause your program to freeze up until the threads are done.
  }
}

Note, this code is not tested. As mentioned before, threading only becomes faster than single threading in certain situations. If you want a thread just so your main program doesn’t freeze up when preparing thousands of particles, the first solution will work fine for that, assuming that you don’t use the myThread.join(). Concerning the second solution, the only thing that the thread is doing is initializing a particle and adding it to an ArrayList, so it isn’t really doing much computation. Furthermore, the necessary ArrayList synchronization actually prevents the thread from being concurrent when adding to the ArrayList and can lose a bit of extra time in the thread scheduler. I’m glossing over how these threading systems work, but what you should know about these solutions is

  • A single extra thread using Runnable should be fine to stop the program from freezing, and should bypass the inability to use thread("methodName")
  • Multithreading can be useful, but mostly for concurrent computation, not data storage
  • Single threading can be faster for smaller datasets
1 Like