繁体   English   中英

如何在 Java 中正确执行线程回调?

[英]How to properly do a thread callback in Java?

我正在开发一个 Java 项目(没有 Android)。 我有一个线程可以完成一些长时间的工作,我希望在工作完成时调用主线程中的一个函数。 我已经看到很多关于这个问题的问题,但似乎没有任何答案有效。 我当前的实现如下所示:

  • 有一个带有回调函数的接口
  • 将该接口作为 runnable 中的参数
  • 在主类中实现它,然后创建runnable并启动一个新线程。
  • 在回调函数上,打印当前线程名称

这是行不通的,因为当线程完成时,它总是打印新线程的名称,而不是主线程的名称。 如何在主线程不是新线程调用回调函数?

谢谢!

编辑:这是我尝试过的代码:

import java.util.Random;

public class ATestThreadClass {
    public static void main(String[] args) {
        new Thread(new RandomRunnable(data -> {
        System.out.println("Called on " + Thread.currentThread().getName());
        System.out.println(data.toString());
    })).start();
}

    static class RandomRunnable implements Runnable {
    private final CallbackInterface callbackInterface;

    public RandomRunnable(CallbackInterface callbackInterface) {
        this.callbackInterface = callbackInterface;
    }

    @Override
    public void run() {
        // Do some very long work...
        Random random = new Random();
        RandomCallbackData data = new RandomCallbackData();
        data.a = random.nextInt(100);
        data.b = random.getClass().getSimpleName();
        data.c = random.nextLong();
        callbackInterface.callback(data); // THIS REALLY NEEDS TO BE CALLED ON THE MAIN THREAD
    }
}


interface CallbackInterface {
    void callback(RandomCallbackData data);
}

static class RandomCallbackData {
    public int a;
    public String b;
    public long c;

    @Override
    public String toString() {
        return "RandomCallbackData{" +
                "a=" + a +
                ", b='" + b + '\'' +
                ", c=" + c +
                '}';
        }
    }
}

(抱歉,格式很奇怪;当我粘贴代码时,堆栈溢出会弄乱它)

以下是日志:

Called on Thread-3
RandomCallbackData{a=77, b='Random', c=-7871432476136355770}

Process finished with exit code 0

以下可能不是最好的答案,所以如果有更好的地方,请纠正我。 这是我的代码:

Main Class:
https://pastebin.com/hSZjGWsr

Holder class for tasks:
https://pastebin.com/eme9nqtA

Callback code:
https://pastebin.com/JvXadT0L

Worker thread code:
https://pastebin.com/fZYdfn9m

很多这些都可以用纯 Java 来完成,但是全部手工编写更容易理解。

以下是其工作原理的摘要:

  • 有一个工作线程类。 当您调用方法.get() ,线程返回最终值。 您还可以调用.isDone()来确定线程是否已完成。
  • 一个列表存储了一个持有者类,它跟踪工作线程及其回调。 方法update旨在循环调用。
  • 当一个线程完成时,相应的回调函数会被调用并带有它的返回值。 然后线程停止,任务从列表中删除。
  • 您可以定义检查任务是否存在竞争的频率。 如果您的应用程序需要立即调用回调,请传入 0 或 1 作为构造函数中的第一个参数。 否则,传入您希望事物以毫秒为单位更新的速度。
  • 当您不再使用该系统时,您应该调用方法markComplete

有关其工作原理的更多信息,请参阅我在代码中添加的注释。

我知道我的实现需要一个循环,这意味着它不是最好的选择。 不过,这是我能想到的唯一方法。 再次,如果有更好的方法,请纠正我。

希望这可以帮助! ;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM