1

httpリクエストを送信してドキュメントをフェッチできるプログラムを開発しています。私はすべてのリクエストアイテムでキューを埋めました:

Queue<RequestItem> requestItems = buildRequest4Docs();

それで、

int threadNum = requestItems.size();
        //ExecutorService exs = Executors.newFixedThreadPool(threadNum);

        for (int i = 0; i < threadNum; i++) {
            ResponseInterface response = new CMSGOResponse();
            RequestTask task = new RequestTask(requestItems.poll(), this, response);
            task.run();
            //exs.execute(new RequestTask(requestItems.poll(), this, response));
        }
        //exs.shutdown();

ここで混乱しています。forループでは、タスクは同時に実行されますか?それともタスクは1つずつ実行されますか?

ありがとう!

4

6 に答える 6

4

これで、タスクが1つずつ実行されます。コメントとして取得したコードのコメントを解除し、行にコメントRequestTask task = new RequestTask(requestItems.poll(), this, response);task.run();付けると、同時実行が可能になります。

したがって、同時実行の場合は、次のようになります。

int threadNum = requestItems.size();
ExecutorService exs = Executors.newFixedThreadPool(threadNum);

for (int i = 0; i < threadNum; i++) {
    ResponseInterface response = new CMSGOResponse();
    exs.execute(new RequestTask(requestItems.poll(), this, response));
}
exs.shutdown();
while (! exs.isTerminated()) {
    try {
        exs.awaitTermination(1L, TimeUnit.DAYS);
    }
    catch (InterruptedException e) {
        // you may or may not care here, but if you truly want to
        // wait for the pool to shutdown, just ignore the exception
        // otherwise you'll have to deal with the exception and
        // make a decision to drop out of the loop or something else.
    }
}

それに加えて、で作成されたスレッドの量を、作業するタスクの量にバインドしないことをお勧めしますExecutorService。通常、ホストシステムのプロセッサの数に接続することをお勧めします。プロセッサの数を取得するには、次を使用します。Runtime.getRuntime().availableProcessors()

そして、このように初期化されたエグゼキュータサービスに、キューのアイテムを配置します。Queueただし、追加のデータが返されないまでをポーリングするのではなく、合計サイズを取得しなくてもうまく機能します。

私の提案の最終結果は次のようになります。

final int threadNum = Runtime.getRuntime().availableProcessors();
final ExecutorService exs = Executors.newFixedThreadPool(threadNum);

while (true) {
    final RequestItem requestItem = requestItems.poll();
    if (requestItem == null) {
        break;
    }
    final ResponseInterface response = new CMSGOResponse(); 
    exs.execute(new RequestTask(requestItem , this, response));
}
exs.shutdown();
于 2012-07-23T09:14:45.127 に答える
4

ここで混乱しています。forループでは、タスクは同時に実行されますか?それともタスクは1つずつ実行されますか?

あなたが投稿したコードでは、あなたが呼び出した(のサブクラスであると仮定して)RequestTaskThreadrunので、それらは1つずつ実行されます。を呼び出す必要がありますstartRequestTask実装について説明Runnableしたので、正しいコードは呼び出さずstart(コードがありません!)、むしろ呼び出しますnew Thread(task);(しかし、あなたは今、それを行う別の方法であるに関して良い答えを受け取ったようですExecutorService。)

代わりに別のスレッドでstartを呼び出すstartと仮定すると、そうです、それらはすべて並行して実行されます(ハードウェアなどで可能な限り)。

于 2012-07-23T09:03:40.760 に答える
2

現在、スレッドを順番に実行していますが、スレッドを実行する方法は2つあります(RequestTaskがスレッドを拡張すると仮定します)

I.スレッドオブジェクトを作成し、start()メソッドを呼び出します。

RequestTask task = new RequestTask(requestItems.poll(), this, response);
task.start(); // run() method will be called, you don't need to call it

II。またはExecutorServiceを作成します

ExecutorService pool = Executors.newFixedThreadPool(poolSize);
//....
for (int i = 0; i < threadNum; i++) {
    ResponseInterface response = new CMSGOResponse();
    RequestTask task = new RequestTask(requestItems.poll(), this, response);
    pool.execute(task);
}
于 2012-07-23T09:13:34.157 に答える
1

現在のスレッドでそれらを1つずつ実行しています。それらを同時に実行するには、ExecutorServiceを使用する必要があります。

于 2012-07-23T09:03:26.527 に答える
1
I am confused here, in the for loop,does the tasks run simultaneously? Or the tasks run one by one?

タスクは同じスレッドで実行されます。つまりone by one、それを呼び出しているため、新しいスレッドではタスクが実行されませんrun()start

        int threadNum = requestItems.size();
        ExecutorService exs = Executors.newFixedThreadPool(threadNum);


        ResponseInterface response = new CMSGOResponse();
        RequestTask task = new RequestTask(requestItems.poll(), this, response);

        exs.execute(task );        
        exs.shutdown();

上記の場合、タスクは新しいスレッドで実行され、10個の異なるタスクを割り当てるとすぐに、ExecutorServiceそれらは異なるスレッドで非同期に実行されます。

于 2012-07-23T09:17:50.087 に答える
0

私は通常、スレッド(またはインターフェイスを実装するクラス)を作成し、start()メソッドを使用してスレッドを起動する傾向があります。

あなたの場合、RequestTaskはRunnableを実装しているので、次のようなstart()メソッドを追加できます。

public class RequestTask implements Runnable {
    Thread t;
    boolean running;

    public RequestTask() {
        t = new Thread(this);
    }

    public void start() {
        running = true;    // you could use a setter
        t.start();
    }

    public void run() {
        while (running) {
            // your code goes here
        }
    }
}

、 それから :

int threadNum = requestItems.size();
RequestTask[] rta = new RequestTask[threadNum];

// Create the so-called Threads ...
for (int i=0;i<threadNum;i++) {
    rta[i] = new RequestTask(requestItems.poll(), this, new CMSGOResponse());
}

// ... THEN launch them
for (int i=0;i<threadNum;i++) {
    rta[i].start();
}
于 2012-07-23T12:42:24.150 に答える