Реализация обратных вызовов в Java с помощью Runnable
Я использую для написания кода на 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();
}
}
Вопрос: правильный ли подход?
Ответы
Ответ 1
просто передайте интерфейс (реализация обратного вызова) к вашей 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
}
}
и простой учебник обо всем, что вам нужно о потоке здесь
Ответ 2
Ваш код очень сложный - вы расширяете 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();