5

タスクの送信が発生するたびに一定数のスレッドを実行するためにスレッドプーリングがどのように実装されているかについて尋ねる必要があります。(Executor では、毎回スレッドの作成と削除のオーバーヘッドを回避するため)

executor.submit(Runnable)

最初にいくつかのスレッドを作成し、タスクが来ると、任意の Queue impl を使用してそれら (スレッド) にタスクを割り当てます。しかし、そのタスクを完了した後、スレッドのライフサイクルに従って、スレッドが再びプールに戻る方法はありますか

「run メソッドの実行後、TERMINATED 状態になり、再度使用することはできません」

queue に対して任意のタスクを実行するための一定数のスレッドを保持するためにスレッドプールがどのように機能するかがわかりません。

task の完了後にスレッドを再利用する例を誰かが教えてくれれば幸いです。

!!前もって感謝します 。!!

4

5 に答える 5

3

「run メソッドの実行後、TERMINATED 状態になり、再度使用することはできません」

終了しませんrun()代わりに、提供したタスクの run() を実行するループがあります。


スレッド プール パターンを大幅に単純化すると、次のようなコードになります。

final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();

public void submit(Runnable runs) {
    tasks.add(runs);
}

volatile boolean running = true;

// running in each thread in the pool
class RunsRunnable implement Runnable {
    public void run() {
        while(running) {
           Runnable runs = tasks.take();
           try {
              runs.run();
           } catch(Throwable t) {
              // handles t
           }
        }
    }
 }

この例では、各タスクの run() が完了している間、スレッド自体の run() はプールがシャットダウンされるまで完了していないことがわかります。

于 2012-10-06T12:30:19.410 に答える
1

通常、スレッド プールを使用するとどうなるか、その内部で Run メソッドを繰り返し実行する必要があります。キューに使用可能なタスクができるまで。

以下の例では、pool.removeFromQueue() が繰り返し実行されます。

public class MyThread<V> extends Thread {
    private MyThreadPool<V> pool;
    private boolean active = true;

    public boolean isActive() {
        return active;
    }

    public void setPool(MyThreadPool<V> p) {
        pool = p;
    }

    /**
     * Checks if there are any unfinished tasks left. if there are , then runs
     * the task and call back with output on resultListner Waits if there are no
     * tasks available to run If shutDown is called on MyThreadPool, all waiting
     * threads will exit and all running threads will exit after finishing the
     * task
     */
    @Override
    public void run() {
        ResultListener<V> result = pool.getResultListener();
        Callable<V> task;
        while (true) {
            task = pool.removeFromQueue();
            if (task != null) {
                try {
                    V output = task.call();
                    result.finish(output);
                } catch (Exception e) {
                    result.error(e);
                }
            } else {
                if (!isActive())
                    break;
                else {
                    synchronized (pool.getWaitLock()) {
                        try {
                            pool.getWaitLock().wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    void shutdown() {
        active = false;
    }

スレッドプールを設計する必要がある

public MyThreadPool(int size, ResultListener<V> myResultListener) {
        tasks = new LinkedList<Callable<V>>();
        threads = new LinkedList<MyThread<V>>();
        shutDown = false;
        resultListener = myResultListener;
        for (int i = 0; i < size; i++) {
            MyThread<V> myThread = new MyThread<V>();
            myThread.setPool(this);
            threads.add(myThread);
            myThread.start();
        }
    }
于 2016-03-08T13:40:42.377 に答える
0

詳細と実装例については、http : //www.ibm.com/developerworks/library/j-jtp0730/index.html を参照してください。プール内のスレッドは、キューが空の場合に待機し、キューにいくつかの要素があることが通知されると、consome メッセージを開始します。

于 2012-10-06T12:31:11.167 に答える
0

ExecutorService executor = Executors.newFixedThreadPool(2);

-上記のステートメントは、固定サイズ 2 の ThreadPool を作成しました。

executor.execute(new Worker());

-上記のステートメントは、RunnableInterface を実装したクラス Worker のインスタンスを取ります。

-ここでExecutorsは、タスクを実行する中間オブジェクトです。スレッド オブジェクトを管理します。

-上記のステートメントを実行すると、run()メソッドが実行され、run() メソッドが完了すると、スレッドはデッド状態にならずにプールに戻り、別の作業が割り当てられるのを待って、再び移動できるようになります。 Runnable 状態になり、次に実行されます。これはすべて Executors によって処理されます。

executor.shutdown();

-上記のステートメントは、Executor 自体をシャットダウンし、それによって管理されるすべてのスレッドのシャットダウンを適切に処理します..shutdown()その中央オブジェクト上で、登録された各 Executor を終了する可能性があります。

////////// Edited Part//////////////////////

-まず、Runnable には何も返さない run() メソッドがあり、run() メソッドはチェック例外をスローできないため、Callable は Java 5 で導入された Parametric 型で、call() というメソッドがあります。を返し、Checked 例外をスローすることができます。

次の例を参照してください。

Thread t = new Thread(new Worker());

t.run();

t.start();

- メソッドt.run()への単なる呼び出しであり、これは.run()thread of execution

- 一方、のt.start()にとって重要なことを準備し、のメソッドを呼び出して、 を新しく形成された に割り当てすぐに戻ります....initializationthread of executionrun()RunnableTask thread of execution

と を使用する場合、Java のスレッドが必要にSwingなりAWTます。主に GUI コンポーネント

于 2012-10-06T12:50:33.543 に答える
0

私はピーターに完全に同意しますが、明確な理解のために、ExecutorService の実行フローに関連する手順を追加したいと考えています。

  • スレッドのプール (固定サイズ プール) を作成しても、スレッドが作成されたことにはなりません。
  • 新しいタスクを送信および/または実行すると (Runnubleまたは) 新しいスレッドが作成されます。作成されたスレッドの数がプールのサイズのCallable場合、JUTS<
  • 作成されたスレッドはプールに戻りません。スレッドはブロッキング キューで新しい値を待つことができます。この時点で RETURNING TO POOL を呼び出すことができます
  • 上記の Peter などのプール exec からのすべてのスレッド。
于 2012-10-06T14:30:53.370 に答える