21

I'm used to write code in JavaScript-like or Erlang-like languages, where I can make callback functions in easy way. Now I have to write something in Java. I figured it out how to perform callback like this:

import java.util.*;

class Demo extends Thread{

    private int data;

    public void run(){
        ask_for_data(new Runnable(){
            public void run(){
                on_data();
            }
        });
    }

    public void on_data(){
        System.out.println("Async callback: " + data);
    }

    public void ask_for_data(final Runnable callback){
        System.out.println("2");
        Runnable r = new Runnable(){
            public void run(){
                data = get_data();
                new Thread(callback).start();
            }
        };
        new Thread(r).start();
    }

    public int get_data(){
        try{
            Thread.sleep(1000);
        } catch (Exception e) {};
        return 42;
    }

    public static void main(String[] args) {
        Demo d = new Demo();
        d.start();
    }
}

Question is: is it correct approach?

zie1ony
  • 1,190
  • 2
  • 14
  • 33

2 Answers2

46

simply pass an interface (callback implementation) to your runnable like this

interface Callback {
    void callback(); // would be in any signature
}

class MyThread implements Runnable {

    Callback c; 

    public MyThread(Callback c) {
        this.c = c;
    }

    public void run() {
        // some work
        this.c.callback(); // callback
    }
}

and a simple tutorial about everything you need about thread here

JJD
  • 50,076
  • 60
  • 203
  • 339
7

Your code is very complicated - you extend Thread, implement Runnable internally and within the Runnable create another Thread. That's not correct approach.

Interface Runnable can be considered as a command design pattern - it's a unit of work to be done and it has been designed to separate logic of "what have to be done" from the threading mechanisms.

I don't know if I get your problem correctly, but from what I understand, you just try to pass some parameters to the callback being run in separate thread. So why don't just introduce some class implementing Runnable (that's your unit of work to be done) and pass by constructor some work parameters. What I mean is something like below:

public class MyUnitOfWork implements Runnable {
  private final Data data;

  public MyUnitOfWork(final Data data) {
    this.data = data;
  }

  public void run() {
    // do something with data
  }
}

and later on:

Thread t = new Thread(new Data(/* something */));
t.start();
omnomnom
  • 8,911
  • 4
  • 41
  • 50
  • You are right, but in my case `MyUnitOfWork` don't has to known what to do on callback - just run it. Sometimes it's very useful. – zie1ony Jun 22 '13 at 22:09