run object method in parallel thread

Hi everybody, i know how to run a function in a parallel thread (easy, just passing the name in "thread()"), but is there a way to run an object method in a parallel thread? Thanks

Answers

  • edited August 2016

    Anything invoked under a Thread is run by it too. O:-)
    Just be careful not to invoke Processing's API which are related to the main canvas. :-SS

  • but like, what would be the sintax? like thread("myObj.myMethod()") ?

  • edited August 2016
    • Just use the thread()'s function as a wrapper for your other methods.
    • In the example below, PVector's add() method is invoked by 2 threads at the same time.
    • That is, sketch's "Animation Thread" and the Thread created by thread().
    • However, given the situation the same object is being modified by more than 1 Thread at the same time, the final result is undefined. 3:-O
    • In my computer I've got [ 10.0, 40.0, 0.0 ] instead of the expected [ 30.0, 40.0, 0.0 ]! 8-}
  • final PVector vec = new PVector();
    
    void setup() {
      thread("anotherThread");
    
      vec.add(10, 10);
      println(Thread.currentThread());
      println(vec);
    
      exit();
    }
    
    void anotherThread() {
      vec.add(20, 30);
      println(Thread.currentThread());
    }
    
  • edited August 2016

    I see, but in this way you need to create already a function for any method of any object you could possibly call. I was thinking it was somehow possible pass a different argument or kind of pointer? Anyway, I'm getting crazy on a very simple stuff. I just want to write a little program who allow to select a bicromatic gif and convert it in a vector grid depending of black and white pixels.

    I can't! It crash all of the time. I guess is because of the loading time, so i tried to use "requestImage", but still it don't work.

    I want to use a thread to show in the draw kind of a progress bar when during the conversion.

    Here is my code, for the moment the vector conversion is still not there, sinc ei can't even loop between the pixels:

    PImage img;
    boolean converting = false;
    void setup()
    {
      size(300, 300);
    }
    
    void draw()
    {
      background(100);
      text("press L to start", 30, 30);
      rect(millis() / 10 % width, height-10, 5, 5);
    
      if (img != null && img.width > 0 && !converting ) {
          println("convert image, dimensions: " + img.width + " " + img.height);
    
        converting = true;
        thread("conversion");
      }
    }
    
    void keyPressed()
    {
     if (key == 'l' || key == 'L'){
       selectInput("Select a file to process:", "imageChosen");
     }
    }
    void imageChosen( File f )
    {
      if ( f.exists() )
      {
        img = requestImage( f.getAbsolutePath() );
      }
    }
    
  • edited August 2016

    I can't! It crash all of the time.

    Remember what I've 1st warned about:

    Just be careful not to invoke Processing's API which are related to the main canvas.

    Also the function called back by selectInput() and its siblings is run by another Thread just like thread().

  • Ok it finally worked removing the "println" inside the pixel looping and just putting geomerative svg generation code. What do you mean exactly with API's related to the main canvas? It is "prinltn" one of those?

    This is interesting to me, but also about the initial question: the system you suggested require to write a function to incapsulate any object.method i want to run in parallel. How if i want to do it in a dynamic way like from an array of objects?

  • ... to write a function to encapsulate any object's method I want to run in parallel.
    How if I want to do it in a dynamic way like from an array of objects?

    That's the very 1st thing I've said:

    Anything invoked under a Thread is run by it too.

    Just have a function to encapsulate as many method calls you need there.

    What do you mean exactly with API's related to the main canvas? It is prinltn() one of those?

    By API take a look here: https://Processing.org/reference/

    And no, println() doesn't depend on or isn't related to sketch's canvas.
    Those'd be rect(), fill(), translate(), etc.

    BtW, even though color() doesn't affect the canvas, it's not Thread-safe at all! @-)

  • edited August 2016

    As a reminder of what I've tipped about already, selectInput() doesn't halt/block currentThread() b/c it creates its own Thread.

    Therefore you can display your progress bar or whatever at the same time the user is still picking some file, while under the "Animation Thread". :-bd

  • Answer ✓

    but is there a way to run an object method in a parallel thread?

    Yes but you have to do some of the work yourself. In this sketch there are 2 classes

    Threader is responsible for running our method in a separate thread. When the Threader object is created you must pass the name of the method and the object to execute it.

    Foo a dummy class which has the method to be executed in a thread.

    Note that the Threader class can be used with any user defined class not just Foo

    int nbr = 5;
    Foo[] foos = new Foo[nbr];
    Threader[] threaders = new Threader[nbr];
    
    void setup() {
      size(400, 400);
      for (int i = 0; i < foos.length; i++) {
        foos[i] = new Foo(i);
        threaders[i] = new Threader(foos[i], "display");
      }
    }
    
    void keyTyped() {
      if (key == 's') {
        for (int i = 0; i < foos.length; i++) 
          threaders[i].start();
      }
    }
    
    void draw() {
    }
    
    
    class Foo {
      int n;
    
      Foo(int n) {
        this.n = n;
      }
    
      void display() {
        for (int i = 0; i < 5; i++)
          print(n + " ");
      }
    }
    
    class Threader extends Thread {
    
      Object object;
      java.lang.reflect.Method method = null;
    
      Threader(Object obj, String name) {
        object = obj;
        try {
          method = object.getClass().getMethod(name, new Class[] {});
        } 
        catch (NoSuchMethodException nsme) {
          System.err.println("There is no public " + name + "() method " +
            "in the class " + getClass().getName());
        }
      }
    
      public void run() {
        if (method != null) {
          try {
            method.invoke(object, new Object[] { });
          } 
          catch (IllegalArgumentException e) {
            e.printStackTrace();
          } 
          catch (IllegalAccessException e) {
            e.printStackTrace();
          } 
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
    
  • I have to do some test about it but seems what i was searching for. I have to take some time and study the pure java part asap. Maybe i'll have more question but thank you!

Sign In or Register to comment.