3

正しい方法を使用して別のスレッドで何かを呼び出すかどうか疑問に思っています。Androidでやっていますが、一般的なJavaの質問だと思います。

いくつかのパラメーターを持つメソッドがあります。それらがintであるとしましょう。

class Main1 {
  public static void mainOnlyWork(int x, int y) {
     // not important here.
  }
}

class Test {
  Handler mHandler;

  // called from main thread, stored as reference.
  public Test() {
    mHandler = new Handler();
  }

  public static void callInMainThread(final int x, final int y) {
    mHandler.post(new Runnable() {
      public void run() {
        Main1.mainOnlyWork(x, y);
      }
    });
  }

私の質問は、最終的な int を使用して、クラス メンバーなしで匿名の実行可能ファイルを作成しても安全ですか? x パラメーターと y パラメーターの final キーワードを省略すると、Eclipse が文句を言います。そのような場合に定数のみを使用することを意図しているように思えます。定数でなくても大丈夫ですか?Javaはこの関数に渡すことでそれを定数にしますか?

しかし、JNI を使用してネイティブから Test.callInMainThread を呼び出したいと考えています。私の意見では、これらの数値が定数であるかどうかをJavaが判断できる方法はありません。Java を信頼して魔法をかけることはできますか? 常にこのように機能しますか?

次のようなプロキシクラスを作成する必要があると思います。

private abstract RunnableXY implements Runnable {
  public RunnableXY(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int x;
  public int y;

  public abstract void run();
}

そして call メソッドは以下を使用します:

  public static void callInMainThread(final int x, final int y) {
    mHandler.post(new RunnableXY(x,y) {
      public void run() {
        Main1.mainOnlyWork(this.x, this.y);
      }
    });
  }

このようにして、ランナブルが使用されて破棄されるまで、ガベージ コレクションから値を保護します。ラッパーを作成する必要がありますか、それともメソッド パラメーターで最終的な x をマークしても安全ですか? 試してみると、 final キーワードは問題なく動作します。ただし、スレッドでは、現在機能するかどうかが常に機能する理由だとは思いません。最終的には常に機能しますか?あるとしたらどのように作られていますか?パラメータがプリミティブ型ではなくオブジェクトの場合、違いはありますか?

更新: Java で final が何を意味するかは既に理解しています。それは問題ではありません。問題は、Runnable の作成に使用される変数のスコープがどこにあるかです。それらはローカルです。つまり、関数の終了後は値を参照できません。Runnable オブジェクトが他のスレッドに渡され、実行されるのを待つとき、その値はどこに保存されますか?

4

3 に答える 3