6

私は次の点で混乱しています:
Java プログラムでスレッドを使用するための最も簡単な方法は、Thread クラスを拡張し、実行可能なインターフェースを実装する (または単に実行可能なものを実装する) ことです。
スレッドの実行を開始します。スレッドのメソッド start() を呼び出す必要があります。これにより、スレッドのメソッド run() が呼び出されます。そして、スレッドが開始されます。
メソッド start() (私が間違っていない限り)は、スレッドごとに1 回だけ正確に呼び出す必要があります。その結果、スレッドの再利用のカスタム実装を容易にする無限ループの短い部分で run メソッド自体が何らかの方法で実行されない限り、スレッド インスタンスを再利用することはできません。
現在、javadoc リンクテキスト

実行する呼び出しは、利用可能な場合、以前に構築されたスレッドを再利用します

これがどのように実装されているかわかりません。executor メソッドの execute メソッドで、カスタム スレッドを提供します。

  ExecutorService myCachedPool = Executors.newCachedThreadPool();
  myCachedPool.execute(new Runnable(){public void run(){  
     //do something time consuming

  }});

エグゼキュータ フレームワークに委任したこのカスタム スレッドを再利用するにはどうすればよいですか?
Executor はメソッド start() を複数回呼び出すことができますが、プログラムではできませんか? 私は何か誤解していますか?

ありがとうございました。

4

3 に答える 3

5

Executorそれはその呼び出しではないことに注意してくださいstart()-それはExecutorServiceです。いいえ、2回呼び出しているわけではありませんstart()。...を使用して直接指定したタスクを開始するのではThread.start()なく、そのスレッドプールの作業キューを認識しているスレッドを開始します。スレッドは基本的に、実行する作業があるまで待機し、それを取得して実行してから、待機に戻ります。したがって、スレッドはいくつかのタスクを実行しますが、Thread.start()呼び出されるのは1回だけです。

Runnable編集:コメントから判断すると、(実行されるタスクである)と(タスクを実行するもの)の違いについて少し混乱していますThread

同じスレッドで複数のタスクを実行できます。スレッドプールを使用しない非常に単純な例については、次のことを考慮してください。

public class MultiRunnable implements Runnable
{
    private final List<Runnable> runnables;

    public MultiRunnable(List<Runnable> runnables)
    {
        this.runnables = runnables;
    }

    public void run()
    {
        for (Runnable runnable : runnables)
        {
             runnable.run();
        }
    }
}

(複数のスレッドからを使用することによる潜在的なスレッドセーフの問題は無視してList<T>ください。)

さまざまなことを実行できる一連のタスクを作成してから、それらを順番に実行するRunnable単一のタスクを作成することができます。MultiRunnableそのインスタンスをコンストラクターに渡しますMultiRunnableThreadスレッドを開始すると、元の実行可能なタスクがそれぞれ実行されます。それは役に立ちますか?

于 2010-09-19T11:23:44.267 に答える
5

start()を2回以上呼び出すことはありません。代わりに、プール内のスレッドは完了しませんが、生きたままになります---待機します。ソースコードをご覧になりたい場合は、ダウンロードしてご利用いただけます。

スレッドプール内の各スレッドはwait()、エグゼキュータが新しいRunnableを渡すことができますが、スレッド自体のrun()メソッドは完了していません。新しいRunnableがエグゼキュータに渡されるのを待つだけです。

于 2010-09-19T11:24:31.097 に答える
1

スレッドを複数回「開始」するには、ランナブルを作成します。例えば:

//NO
private class T extends Thread { //not necessary to implement runnable
    public void run(){
        //...
    }
}
void someMethod(){
    T a = new T();
    a.start();
    a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
}

その代わり、

//Yes
private class T implements Runnable {
    public void run(){
        //...
    }
}
void someMethod(){
    T a = new T();
    new Thread(a).start();
    new Thread(a).start(); //YES YES YES
}

これを行うことも可能です:

void someMethod(){
    final Runnable r = new Runnable(){
        public void run(){
            //...
        }
    };
    new Thread(r).start();
    new Thread(r).start();
}
// r could also be a field of you class. 
于 2010-09-19T13:44:44.180 に答える