簡體   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