Реализация обратных вызовов в Java с помощью Runnable - программирование
Подтвердить что ты не робот

Реализация обратных вызовов в 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();
    }
}

Вопрос: правильный ли подход?

4b9b3361

Ответ 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();