使用Runnable在Java中实现回调

时间:2013-06-22 21:30:05

标签: java asynchronous

我习惯用类似JavaScript或类似Erlang的语言编写代码,在那里我可以轻松地创建回调函数。现在我必须用Java写一些东西。我想出了如何执行这样的回调:

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();
    }
}

问题是:这是正确的方法吗?

2 个答案:

答案 0 :(得分:35)

只需将接口(回调实现)传递给您的runnable,就像这样

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
    }
}

以及关于线程here

所需的一切简单教程

答案 1 :(得分:7)

您的代码非常复杂 - 您在内部Thread扩展Runnable,在Runnable内创建另一个Thread。这不是正确的方法。

接口Runnable可以被视为一种命令设计模式 - 它是一个工作单元,它被设计为分离逻辑“必须做什么”线程机制。

我不知道我是否正确地解决了您的问题,但据我所知,您只是尝试将一些参数传递给在单独线程中运行的回调。那么为什么不介绍一些实现Runnable的类(这是你要完成的工作单元)并通过构造函数传递一些工作参数。我的意思是如下所示:

public class MyUnitOfWork implements Runnable {
  private final Data data;

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

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

以及后来:

Thread t = new Thread(new Data(/* something */));
t.start();