ホームページ  >  記事  >  Java  >  Java コールバック メカニズムの概要

Java コールバック メカニズムの概要

尚
転載
2020-06-17 17:06:342332ブラウズ

Java コールバック メカニズムの概要

モジュール間呼び出し

アプリケーション システムでは、開発にどの言語が使用されるかに関係なく、

(1) 同期呼び出し

同期呼び出しは、最も基本的かつ単純な呼び出し方法です。クラス A のメソッド a() は、クラス B のメソッド b() を呼び出します。メソッド b() の実行が終了し、メソッド a() が続行されるまで待機します。 この呼び出しメソッドは、メソッド b() の実行時間が長くない状況に適しています。 メソッド b() の実行時間が長いか、直接ブロックされている場合、メソッド a() の残りのコードは実行できず、プロセス全体がブロックされます。

(2) 非同期呼び出し

非同期呼び出しは、同期がブロックされる可能性がある問題を解決するためのものです。呼び出しが行われ、プロセス全体がスタックすることによってメソッドの呼び出しが行われます。 クラス A のメソッド a() は、新しいスレッドを開始することでクラス B のメソッド b() を呼び出し、コードは直接実行されます したがって、メソッド b の実行時間とは関係ありません。 () メソッド a() の実行がブロックされるまでどのくらい時間がかかりますか?

しかし、このように、メソッド a() はメソッド b() の実行完了を待たないため、メソッド a() がメソッド b() の実行結果を必要とする場合、 (具体的な状況による)業務により異なる(WeChat通知を送信するための非同期スレッドの開始やキャッシュのリフレッシュなど一部の業務では不要)メソッドb()の実行結果を監視する必要があるある意味で。

#(3) コールバック

最後にコールバックです。コールバックの概念は次のとおりです。

#クラス A の a() メソッドは、クラス B の b() メソッドを呼び出します
  • ##クラス A の b() メソッドクラス B は、実行後にクラスを積極的に呼び出します。クラス A の callback() メソッド
  • このような呼び出しメソッドは、上の図を形成します。 双方向
メソッドを呼び出します。

コード例

次にコールバック コード例を見てみましょう。コードはシミュレートします。先生が生徒に質問し、生徒が考えて先生に答える、そんな場面です。

最初にコールバック インターフェイスを定義します。このインターフェイスにはメソッド TellAnswer(int Answer) が 1 つだけあります。つまり、生徒は考えた後に教師に答えを伝えます。

/**
 * 回调接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html
 */
public interface Callback {

    public void tellAnswer(int answer);

}

定義: 教師オブジェクトはコールバック インターフェイスを実装します:

/**
 * 老师对象,原文出处http://www.cnblogs.com/xrq730/p/6424471.html
 */
public class Teacher implements Callback {

    private Student student;

    public Teacher(Student student) {
        this.student = student;
    }

    public void askQuestion() {
        student.resolveQuestion(this);
    }

    @Override
    public void tellAnswer(int answer) {
        System.out.println("知道了,你的答案是" + answer);
    }

}
教師オブジェクトには 2 つのパブリック メソッドがあります:

(1) コールバック インターフェイス TellAnswer(int Answer)、つまり生徒が質問に答えました その後、教師がやるべきこと #(2) askQuestion メソッド askQuestion()、つまり生徒に質問する

その後、学生インターフェイスを定義します。学生はもちろん問題を解決しますが、コールバック パラメータを受け取るため、学生は問題解決後に誰に報告するべきかを知ることができます。

/**
 * 学生接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html
 */
public interface Student {

    public void resolveQuestion(Callback callback);

}
最後に、Ricky という名前の特定の学生を定義します。

/**
 * 一个名叫Ricky的同学解决老师提出的问题,原文出处http://www.cnblogs.com/xrq730/p/6424471.html
 */
public class Ricky implements Student {

    @Override
    public void resolveQuestion(Callback callback) {
        // 模拟解决问题
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {

        }

        // 回调,告诉老师作业写了多久
        callback.tellAnswer(3);
    }

}
問題を解いた後、16 行目で教師に答えを報告します。

比較的単純なテスト クラスを作成します:

/**
 * 回调测试,原文出处http://www.cnblogs.com/xrq730/p/6424471.html
 */
public class CallbackTest {

    @Test
    public void testCallback() {
        Student student = new Ricky();
        Teacher teacher = new Teacher(student);

        teacher.askQuestion();

    }

}

コードの実行結果は 1 行です:


<span style="color: #000000;">知道了,你的答案是3<br></span>
簡単に要約します。この例を分析してください。つまり:

(1) 教師は生徒インターフェースのメソッドsolveQuestion を呼び出し、生徒に質問します。 (2) 生徒が問題を解決した後、彼は教師のコールバック メソッド TellAnswer

このような一連のプロセスは、双方向の呼び出し関係を構成します。

コード分析

上記のコードを分析します。上記のコードに対して 2 つの抽象化レイヤーを作成しました。 1) 教師を抽象化する

教師を抽象化した後は、質問に基づいて答えが得られれば、生徒はどの教師が質問したかを気にする必要はありません。質問をした先生です。先生が何度も変わっても生徒には影響しません

(2) 生徒を抽象化します

  • 生徒を抽象化した後は、教師にとって非常に柔軟になります。教師は必ずしも 1 人の生徒に質問する必要はなく、リッキー、ジャック、ルーシーの 3 人の生徒に同時に質問できるためです。 、メンバーを変数 Student を List に変更して、質問するときに Student リストをたどって質問し、各生徒から回答を得ることができるようにします。

この例は、インターフェースの役割を反映した典型的な例です。なぜこのように言ったかというと、インターフェースの利点を理解していない友達もいると思うからです。インターフェースの利点を理解していない友達は、この例に集中できます。もっと理解するために。

要約すると、コールバックの核心は、コールバック パーティが自分自身 (this) を呼び出し元 に渡して、呼び出し元がわかるようにすることです。通話が完了した後のコールバックには、知りたい情報が含まれます。コールバックはアイデアでありメカニズムであり、それをどのように実装するかについては、開発者の個人レベルとビジネスに対する理解に依存します。

同期コールバックと非同期コールバック

上記の例では、誰かが次の質問をするかもしれません:

この例にはどのようなコールバックが必要ですか? 同期呼び出しを使用して、生徒オブジェクトが質問に答え、その答えを教師オブジェクトに直接返すと素晴らしいと思いませんか?

この質問を提起することに問題はありません。この質問は 2 つの角度から理解できます。

まず、教師が生徒からの答えだけを求めていない場合はどうなるでしょうか?

おそらく、この教師は生徒の問題解決のアイデアを聞くことを好む教師です。生徒の答えを得る前に、教師は生徒の名前と生徒の問題解決のアイデアを知りたいと考えています。もちろん、そう言う人もいますが、私もそう言えます。オブジェクトを定義して、生徒の名前と解決策のアイデアを追加するのは良いことではないでしょうか?私の意見では、このステートメントには 2 つの問題があります:

(1) 教師がより多くのデータを必要とする場合、返されるオブジェクトはますます大きくなる必要があり、コールバックを使用するとデータが分離される可能性があります。業務に依存するデータについては、コールバックメソッドにリターンパラメータを追加する必要がある場合はコールバックメソッドに直接追加してください

(2) という問題が解決できない教師は生徒の名前を取得したいと考えています。生徒の問題解決のアイデアは生徒の答えよりも優先されます。

したがって、単純に特定の結果を返すためにコールバックを使用する必要はなく、同期呼び出しを直接使用できると思いますが、処理する必要のあるデータの種類が複数あり、データはプライマリ データとセカンダリ データに分類されるため、コールバックを使用する方が適切です。コールバック メソッドでは、優先順位の高いデータから最初に処理する必要があります。

別の観点からの理解がより重要です。それは、タイトルで述べた同期コールバックと非同期コールバックです。この例は同期コールバックです。これは、教師が Ricky に質問し、Ricky が答え、教師が次のクラスメートに質問し、答えを取得した後、次のクラスメートに質問を続けることを意味します。これは通常のシナリオですが、シナリオを変更します 見てください:

先生は 1 つずつ質問するのではなく、リッキー、マイク、ルーシー、ブルース、ケイトの 5 人の生徒に質問しました。同時に、生徒たちに自分で考えさせ、どの生徒が考えるべきか? 終わったら、その答えを直接教師に伝えてください。

このシナリオは、生徒が問題について考え終えた後、教師に伝える方法が必要であると言うのと同じです。解決策は 2 つあります:

( 1) Future Callable メソッドを使用し、非同期スレッドの実行結果を待ちます。これは同期呼び出しの変形に相当します。その本質は、メソッドが結果、つまり生徒の答えを返すことであるためです。

(2) 非同期コールバックを使用すると、生徒は質問への回答を完了します。コールバック インターフェイス メソッドを呼び出して、教師に答えを伝えるだけです。教師オブジェクトが Callback インターフェイスに抽象化されているため、このアプローチは拡張性が非常に優れています。前述したように、教師が次々に変わっても、生徒にとっては Callback インターフェイスを呼び出すことだけが重要です。必要な情報

さらに関連する知識については、Java 基本チュートリアル

に注目してください。

以上がJava コールバック メカニズムの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。