web-dev-qa-db-ja.com

Javaでのスレッドプールの使用は何ですか?

スレッドプールの用途は何ですか?良い実例はありますか?

36
JavaUser

スレッドプールは、最初に作成され、ジョブを待機して実行するスレッドのグループです。スレッドを常に存在させることで、毎回スレッドを作成するためのオーバーヘッド時間を費やす必要がなくなります。ジョブがない場合もあるかもしれませんが、処理するジョブのストリームがあることがわかっている場合、これらは適切です。

これが Wikipedia のニース図です。 alt text

47
Amir Rachum

スレッドプール Javaチュートリアルからのチュートリアルには、適切な概要があります。

ワーカースレッドを使用すると、スレッドの作成によるオーバーヘッドが最小限に抑えられます。スレッドオブジェクトは大量のメモリを使用し、大規模なアプリケーションでは、多くのスレッドオブジェクトの割り当てと割り当て解除により、メモリ管理のオーバーヘッドが大幅に増加します。

7
Justin Ethier

単純な Google 検索では、Javaスレッドプールおよび一般的なスレッドプールに関する豊富な情報が得られます。

ここにいくつかの役立つリンクがあります:

5
S73417H

スレッドプールは、クライアント要求の数/発生を決定/予測できないサーバー/クライアントの種類の状況でのみ役立ちます。

このシナリオでは、クライアント要求が行われるたびに新しいスレッドを作成することには、2つの欠点があります。

1)スレッド作成のランタイムレイテンシ:スレッドの作成には時間がかかるため、実際のジョブはリクエストが受信されても​​すぐには開始されません。クライアントでわずかな遅延が発生する場合があります。

この基準は、クライアントが即時のアクションを期待するインタラクティブシステムでは重要です。

2)システムリソースの制御されていない使用:スレッドはシステムリソース(メモリなど)を消費するため、これまでにないクライアントリクエストのフローが発生した場合、システムはリソースを使い果たす可能性があります。

スレッドプールは、次の方法で上記の懸念に対処します。
1)実行時にスレッドを作成するのではなく、サーバーの起動時に指定された数のスレッドを作成します。
2)所定の時間に実行されているスレッドの数を制限する。

注:上記は、固定サイズのスレッドプールに適用されます。

5
Avinash Ganta

スレッドプールは、ジョブを実行する準備ができている、既に作成されているワーカースレッドのプールです。 Threadを作成して管理します。 thread-poolは、タスクを実行した後にスレッドを作成して破棄するのではなく、ワーカースレッドの形式でスレッドを再利用します。

なぜ?

スレッドの作成は時間のかかるプロセスであり、リクエストの処理を遅らせるからです。また、JVMごとに許可されるスレッド数に基づいてクライアント数を制限します。これは明らかに制限された数です。


Executorフレームワークを使用して固定サイズのスレッドプールを作成-

Java 5は、一般にExecutorフレームワークとして知られる、フル機能の組み込みスレッドプールフレームワークを導入しました。

Java 5 Executorフレームワークを使用して固定サイズのスレッドプールを作成することは、Executorsクラスによって提供される静的なファクトリメソッドのため、非常に簡単です。必要なことは、同時に実行し、そのタスクをExecutorServiceに送信するタスク。

ここから、スレッドプールがそのタスクの実行方法を処理します。空きワーカースレッドによって実行できます。

public class ThreadPoolExample {
    public static void main(String args[]) {
       ExecutorService service = Executors.newFixedThreadPool(10); //create 10 worker threads in Thread Pool
       for (int i =0; i<100; i++){
           service.submit(new Task(i)); //submit that to be done 
       }
    }  
}

final class Task implements Runnable {
    private int taskId;  
    public Task(int id){
        this.taskId = id;
    }

    @Override
    public void run() {
        System.out.println("Task ID : " + this.taskId +" performed by " 
                           + Thread.currentThread().getName());
    }  
}

Output:
Task ID : 0 performed by pool-1-thread-1
Task ID : 3 performed by pool-1-thread-4
Task ID : 2 performed by pool-1-thread-3
Task ID : 1 performed by pool-1-thread-2
Task ID : 5 performed by pool-1-thread-6
Task ID : 4 performed by pool-1-thread-5

*Output may vary from system to system
5
roottraveller

スレッドを実際のワーカーと見なし、スレッドプールをワーカーのグループと見なすことができます。優先度、目的などのさまざまな理由で複数のグループを作成する場合があります。そのため、1つのプールがバックグラウンドスケジュール、電子メールブロードキャストなどの汎用タスク用である一方で、複数のトランザクションを同時に処理するトランザクション処理プールがある場合があります。エグゼキューターサービスの場合は、確認メールのブロードキャストやデータベースメンテナンスアクティビティなどの重要でない他のアクティビティが完了していない場合、トランザクションジョブの完了を遅らせたくないと思います。それらをプールに分離し、個別に維持することができます。これは、専門用語を使わずに非常に単純な答えです。よろしく、KT

4
Kapil