2012-10-07 12 views
31

runnableに匿名クラスを使用したいと思います。そこ双方向がありますが、それらは同じものか、いない場合、私にはわからない:方法1匿名Runnableクラスを作成して使用する最善の方法

を:直接Runnableを使用し、方法2ラン

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

を呼び出す:匿名の実行可能、およびペーストを作成しますrunの代わりにstartメソッドを使用してスレッドにする:

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

私は方法2が明らかだと思います。しかし、それは方法1と同じことをするかどうかわからないのですか? Runnableのrunメソッドを直接呼び出すことはできますか?

感謝:)あなたがそのようにスレッドバックグラウンドを取得しませんよう

答えて

21

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

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

また、FutureインターフェイスとFutureTasksクラスを使用してRunnablesのように見たい場合は、完了したら結果を返すことができます。 SwingWorkerを使用している場合は、未知のインターフェースを既に使用しています。

1

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

これは、コードを実行可能ファイルの外に置くのと同じです。そこ匿名クラスで定義されたコードに新しいスレッドを起動するには二つの方法、as described in Thread's javadocがあるが、あなたの方法1は、それらの間ではなく、あなたの方法2はあなたが通常好むべきものであること

注意。

1

@Hovercraftは、Runnable.run()メソッドを直接呼び出すと、Threadはまったく作成されません。他の方法(System.out.println(...)、...)を呼び出すのと同じです。あなたが対象となるThreadtargetフィールドを設定しますThreadコンストラクタにRunnableオブジェクト、渡すと

は:次に、あなたがThreadstart()を呼び出すとき

this.target = target; 

を、これはフォークの作業を行います新しいスレッドを呼び出してThread.run()メソッドを呼び出します。Thread.run()は、順番に、ターゲットのrun()メソッドを呼び出します:だからThreadRunnableを渡し、その後start()を呼び出す

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

を別のスレッドでバックグラウンドであなたのRunnableを実行する方法です。

6

あなたの方法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(); 
23

、Threadクラスを使用すると、正しい方法です。ただし、Javas Executorsフレームワークを使用して、実行中のスレッドを処理することも検討する必要があります。

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

もちろん、スレッドを直接使用するだけで問題ありません。しかし、フレームワークを使用することが一般に推奨されています(または推奨されています)。 Javaで詳細を処理しましょう。

+0

この場合、run()メソッドにパラメータを渡す方法はありますか? – kenshinji

+0

@kenshinjiいいえ、あなたはRunnableを実装するクラスのコンストラクタでこれらのパラメータを渡す必要があります。 –

4

私はこのディスカッションに何かを加えたいと思います(あなたはすでに良い答えを得ています)。
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 
2

は、方法1で、それはちょうど、Runnableインタフェースを実装し、それを呼び出すなどの方法のように動作しますが、作成されたバックグラウンドスレッドが存在しません。 startメソッドを呼び出すと、腐食スレッドが実行を開始し、Java仮想マシンはこのスレッドのrunメソッドを内部的に呼び出します。したがって、スレッドを開始するには、Runnableインタフェースを使用してstartメソッドを呼び出す必要があります。 メソッド1では、Runnableインターフェイスがstart()メソッドをサポートしていないため、Runnableインターフェイスリファレンスでstartメソッドを呼び出すことはできません。スレッド実行を開始するThreadクラスのオブジェクトを作成するためには必須です。

0

あなたの方法1は、通常、有用な仕事をすることはできません。このメソッドを使用すると、単純なHelloWorld.javaプログラム、つまり "Hello World"の出力を取得する場合、次の無用なコードに似ていますが、 "Hello World"が出力されます。だから、あなたは第二の方法を使うべきです。無駄なコード:

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

常にRunnableはスレッドで実行したいコードです。

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

そして、あなたはのstart()メソッドを呼び出した後、あなたがこの

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

のような、新しいスレッドを作成したRunnableをスレッドを作成して渡すことができます:匿名のRunnableコードを定義するための一つの方法ですThreadクラスでは、run()メソッドの内部にあるコードが新しく作成されたスレッド上で実行されます。あなたはまた、ここで here

0

をRunnableオブジェクトを作成するための別の方法を探すことができ

は適切に匿名の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 
       } 
      } 
     } 
    } 

} 
関連する問題