2013-06-22 58 views
14

我習慣用類似JavaScript或類似Erlang的語言編寫代碼,我可以通過簡單的方式編寫回調函數。現在我必須用Java編寫一些東西。我想出瞭如何執行回調如下:使用Runnable在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(); 
    } 
} 

問題是:它是正確的方法嗎?

+3

http://codereview.stackexchange.com/ – Reimeus

回答

31

簡單的接口(回調實現)傳遞到您的可運行這樣

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

THX的教程。 – zie1ony

6

你的代碼是非常複雜的 - 你延長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(); 
+0

你是對的,但在我的情況下'MyUnitOfWork'不必知道在回調中做什麼 - 只需運行它。有時候它非常有用。 – zie1ony