web-dev-qa-db-ja.com

匿名のRunnableクラスを作成および使用する最良の方法

Runnableに匿名クラスを使用します。 2つの方法がありますが、同じことを行うかどうかはわかりません。

方法1:Runnableを直接使用してからrun()を呼び出す:

_new Runnable() {
    @Override
    public void run() {
    }
}.run();
_

方法2:匿名のRunnableを作成し、start()の代わりにrun()メソッドを使用して、Threadに貼り付けます。

_new Thread(new Runnable() {
    @Override
    public void run() {
    }
}).start();
_

方法2は明らかに正しいと思います。しかし、方法1と同じことを行うかどうかはわかりません。 Runnablerun()メソッドを直接呼び出すことはできますか?

34
hqt

いいえ、通常、バックグラウンドスレッドをそのように取得しないため、Runnableでrun()を直接呼び出しません。バックグラウンドスレッドが不要で必要な場合は、run()を直接呼び出しますが、バックグラウンドスレッドを作成し、その中からRunnableを実行する場合は、新しいスレッドを作成してから、 Runnableをコンストラクタに渡し、start()を呼び出します。

また、ExecutorsおよびExecutorServicesの使用を含むこのタスクを達成する他の方法があり、ベアボーンThreadオブジェクトを使用するよりも柔軟性とパワーを提供するため、この使用を検討する必要があります。

また、 Future インターフェイスと FutureTasks クラスの使用方法を確認する必要があります。これらのクラスは、実行時にのみ結果を返すことができるRunnablesに似ています。 SwingWorkerを使用したことがある場合は、Futureインターフェースを認識せずにすでに使用しています。

他の人が述べたように、Threadクラスを使用するのが正しい方法です。ただし、Java Executors frameworkを使用して実行中のスレッドを処理することも検討する必要があります。

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override 
    public void run() {
        // code in here
    }
});

もちろん、スレッドを直接使用するだけで十分です。ただし、フレームワークを使用することをお勧めします(または推奨します)。 Javaで詳細を処理してください。

24
jakson

あなたの方法1は意味をなしません。 Runnableインターフェイスは、Thread(メソッド2)内で実行された場合にのみスレッド化に意味があります。インラインでラップする別の方法、スレッド内のコードの塊を見つけたい場合、これは1つかもしれません:

Thread t = new Thread()
{
     public void run()
     {
        // put whatever code you want to run inside the thread here.
     }
};
t.start();
6
ylabidi

私はこの議論に何かを追加したいと思います(あなたはすでに良い答えを得ています)。
Runnableオブジェクトがステートレスの場合、メモリ割り当てを削減するために(時間がかかり+メモリを消費します-アプリケーションがスレッドを大量に使用する場合を考えてください)-runnableオブジェクトを保持する静的フィールドを持つことを検討してください。

private static Runnable runnable = new Runnable() { //Once again - do this only if this is a statelss object!
   public void run() {
   }
} 

//Use the runnable somewhere in the code
4
Yair Zaslavsky

メソッド1では、Runnableインターフェイスがメソッドを実装および呼び出しているメソッドのように機能しますが、バックグラウンドスレッドは作成されません。実際には、startメソッドを呼び出すと、対応するスレッドの実行が開始され、Java Virtual Machineはこのスレッドのrunメソッドを内部的に呼び出します。したがって、スレッドを開始するにはstartメソッドを呼び出す必要がありますRunnable参照インターフェースを使用します。Runnableインターフェースはstart()メソッドをサポートしていないため、メソッド1ではRunnableインターフェース参照を使用してstartメソッドを呼び出すことはできません。

2
Mohamed Sahil

Runnableは、単に必要なコードであるか、スレッドで実行できることを忘れないでください。 Runnableコードを匿名で定義する1つの方法は次のとおりです。

  Runnable codeToRunOnThread=new Runnable() {
      @Override
      public void run() {
      //code to run in a thread you want
      }
  };

そして、スレッドを作成し、作成したRunnableをこの新しいスレッドに渡すことができます

  Thread myThread=new Thread(codeToRunOnThread);
  myThread.start();

Threadクラスのstart()メソッドを呼び出した後、run()メソッド内に入るコードは、新しく作成されたスレッドで実行されます。

Runnableオブジェクトを作成する別の方法を調べることもできます here

1
Krishna Sapkota

最初の方法は間違っています:新しいスレッドを作成しないので役に立たない。

コードを実行可能ファイルの外に置くようなものです。

匿名クラスで定義されたコードで新しいスレッドを起動する2つの方法があることに注意してください。 スレッドのjavadoc で説明されていますが、メソッド1はその中にはなく、メソッド2はあなたが通常好むべきものです。

1
Denys Séguret

@Hovercraftが述べたように、Runnable.run()メソッドを直接呼び出すと、Threadはまったく作成されません。他のメソッド(System.out.println(...)、...)を呼び出すのと同じです。

RunnableオブジェクトをThreadコンストラクターに渡すと、targetThreadフィールドがオブジェクトに設定されます。

_this.target = target;
_

次に、Threadstart()を呼び出すと、新しいスレッドをフォークしてThread.run()メソッドを呼び出します。 Thread.run()は、ターゲットのrun()メソッドを順番に呼び出します。

_public void run() {
    if (target != null) {
        target.run();
    }
}
_

したがって、RunnableThreadに渡してからstart()を呼び出すと、別のスレッドでバックグラウンドでRunnableを実行できます。

1
Gray

通常、メソッド1は有用な作業を実行できません。このメソッドを使用すると、単純なHelloWorld.Javaプログラム、つまり「Hello World」の出力を取得する場合、次のような役に立たないコードに似ていますが、「Hello World」と出力されます。したがって、2番目の方法を使用する必要があります。役に立たないコード:

class MyRunnable implements Runnable {

    public void run() { 
    System.out.println("Hello World");
    }

    public static void main(String[]arg){ 
    MyRunnable myRunnable = new NamedRunnable( );
    namedRunnable.run();
    } 
}
0
Harjit Singh

匿名のRunnableクラスを適切に作成し、メモリリークを処理する方法の簡単なコード例を次に示します(Androidの例):

public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {

            MyRunnable myRunnable = new MyRunnable(this);
            myHandler.postDelayed(myRunnable, TimeUnits);
}

// Must be declared as a static class    
private static class MyRunnable implements Runnable {
        WeakReference<MainActivity> mActivity;
        // Creating weakreference
        MyRunnable(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void run() {
            MainActivity activity = mActivity.get();
            // Checking reference exist or not
            if (activity != null) {
                    //Do necessary tasks
                }
            }
        }
    }

}
0
0xAliHn