2013-06-22 13 views
14

Jestem używany do pisania kodu w językach podobnych do JavaScript lub Erlang, gdzie mogę łatwo wywoływać funkcje wywołania zwrotnego. Teraz muszę napisać coś w Javie. Wymyśliłem, jak wykonać wywołanie zwrotne w ten sposób:Wdrażanie wywołań zwrotnych w języku Java przy użyciu Runnable

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

Pytanie brzmi: czy to właściwe podejście?

+3

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

Odpowiedz

31

prostu zdać interfejs (wdrożenia callback) do swoich runnable jak ten

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

i prosty poradnik o wszystko, czego potrzebujesz na temat wątku here

+1

Thx tutoriali. – zie1ony

6

Kod jest bardzo skomplikowana - rozszerzyć Thread, wdrożenia Runnable wewnętrznie iw ramach Runnable Utwórz kolejny Thread. To nie jest właściwe podejście.

Interfejs Runnable można uznać za wzorzec projektowania poleceń - jest to jednostka pracy do zrobienia i to zostało zaprojektowane do oddzielnym logiką „jakie muszą być zrobione” z mechanizmów gwintów.

Nie wiem, czy problem jest prawidłowy, ale z tego co rozumiem, wystarczy przekazać niektóre parametry do wywołania zwrotnego uruchamianego w osobnym wątku. Dlaczego więc nie wprowadzić klasy implementującej Runnable (to twoja jednostka pracy do wykonania) i przekazać konstruktorowi niektóre parametry pracy. Co mam na myśli coś takiego jak poniżej:

public class MyUnitOfWork implements Runnable { 
    private final Data data; 

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

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

i później:

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

Masz rację, ale w moim przypadku 'MyUnitOfWork' nie musi wiedzieć, co zrobić na oddzwo- wieniu - po prostu go uruchom. Czasami jest to bardzo przydatne. – zie1ony

Powiązane problemy