完全なJavaのスレッドプール

なぜ、スレッドプールを使用します

公式文書には、二つの問題を解決するためのスレッドプールは:まず、非同期タスクの多数の実装では、スレッドプールは、パフォーマンスを向上させるために、など、スレッドを作成スレッドを開始頻繁ななど、タスクの開始前に準備作業を軽減するため、 ;第二は、その上の完成とされているようなタスクの数など、いくつかの基本的な統計分析を行うことができ、リソースとリソースの管理をバインドする方法を提供することです。

ExecutorServiceの

インターフェイスは、タスクが実行可能メソッドを実行実行するために、エグゼキュータから継承されました。ExecutorServiceの管理方法は、Futureオブジェクトによって非同期タスクの進行状況を追跡するために、非同期タスクとメソッドを終了しています。

public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}
复制代码

ExecutorServiceのは、もはや資源をリサイクルすることができ、新しいタスクを受け入れ、その後、オフにすることはできません。拡張メソッドは、オブジェクトが実行をキャンセルしたり、実行が完了するのを待っているの未来を返す、メソッドを実行提出します。バッチ作業することができます。

public interface ExecutorService extends Executor {

    /**
     * 已经提交的任务继续执行,不再接受新的任务
     */
    void shutdown();

    /**
     * 尝试停止正在执行的任务,没有执行的任务不再执行,不再接受新的任务
     * 返回没有执行的任务的列表
     */
    List<Runnable> shutdownNow();

    /**
     * 阻塞直到(所有任务完成(shutdown 后)| 超时 | 当前线程被中断)发生其一
     * 终止时返回 true,反之返回 false
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

    /**
     * 提交新任务,并返回一个 Future 对象用于获取执行结果信息
     */
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);

    /**
     * 执行给定的任务列表,返回任务结果信息的 Future 列表。可设定超时时间
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;

    /**
     * 执行给定的任务列表,返回一个成功完成的任务的结果(如果有)。可设定超时时间
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
复制代码

ThreadPoolExecutor

AbstractExecutorServiceから継承されます。AbstractExecutorService ExecutorServiceのメソッドはFutureオブジェクトを提出達成を支援するために返し、インタフェースを実装し、保護方法newTaskForを追加します。それはタスクまたはタスクのForkJoin種類を遅延しない限り、スレッドプールを使用するプロセスでは、ほとんどの場合、クラスにコンストラクタを使用します。

コンストラクタ

コンストラクタのスレッドプールは4、最終的には以下のコンストラクタに呼び出されますがあります。

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
复制代码
  • corePoolSize:スレッドプール内のスレッドの数はスレッドが無料であっても、維持します。アイドルスレッドがallowCoreThreadTimeOut = trueのときに、タスクのタイムアウト時に破棄されません。

  • maximumPoolSize:飽和後タスクキューは、あなたが新しいスレッドを作成することができます許可スレッドプールの最大内のスレッドの数を示します。

  • keepAliveTimeが:スレッドプール内のスレッド数がアイドルスレッドキープアライブ時間を終了する前に、corePoolSizeよりも大きくなります。

  • 単位:時間の単位。

  • ワークキュー:タスクキュー。のみ提出されたタスクを保存します()ExecutorServiceの方法が実行されます。タスクキューに追加すると、最大音量を超えると、あなたは、処理のためのRejectedExecutionHandlerを使用する必要があります。BlockingQueueのいくつかのデフォルトの実装では、より一般的にそれはLinkedBlockingQueue、SynchronousQueue、ArrayBlockingQueueで使用し、直接、特定のサイズの配列数式キュー(これについての権利を書い背後にある意図)の同期キューのスレッドを作成するキューのリストの実装をリンクされていない制限に対応しています。

  • threadFactory:新しいスレッドファクトリを作成します。あなたは、このようなスレッドを命名し、他の操作を実現できるよう、カスタマイズすることができます。執行は、このようなdefaultThreadFactoryなどの植物の数で実装されている、彼らは独自の要件を満たすように、それは、クラスに基づいて変更することができます。新しいスレッドを返すnewThread方法を達成するために必要。

  • スレッドプールのスレッドおよびキューの最大数が満たされた、その後、タスクは対応できない来た:ハンドラ。あなたはこれらのタスクのオーバーフローに対処する方法を説明するためのRejectedExecutionHandlerが必要な場合です。デフォルトの実装CallerRunsPolicy ThreadPoolExecutor、プロセッサのAbortPolicy、DiscardPolicy、DiscardOldestPolicyいくつかの種類は、それぞれ、直接実行、中断、タスクを無視して、最古のミッションを無視することはありません。私たちは、新しいスレッド処理などの新しいプロセッサをカスタマイズすることができます。

ルールのスレッドを作成します。

新しいタスクは、スレッドプールに提出された場合、いくつかの可能なシナリオが発生するがあります。

  1. 実行されているcorePoolSizeスレッドプールのスレッドよりも少ないがあり、その後、なぜならこの時点でスレッドプールのアイドル状態のいくつかのスレッドは、まだスレッドのコア数、スレッド・プールに達していない場合でも、新しいスレッドを再作成します。
  2. スレッドプールスレッドの数がより大きく、より少ないまたはcorePoolSize maximumPoolSizeに等しく、ワークキューが飽和していない場合、スレッドを再作成しない、タスクキューに新しいタスクを追加します。作業キューが飽和している場合は、新しいスレッドを作成します。
  3. これは、スレッドがこの直接実行スレッドで、無視して、そのような割り込みなどのRejectedExecutionHandler新しい処理タスクを、プール、スレッドの数、スレッドプールと飽和タスクキューmaximumPoolSizeに等しいです。

ScheduledExecutorService与ForkJoinPool

通常の状況下ではほかにThreadPoolExecutorの十分の使用は、単に言及ここで実装ForkJoinPool ForkJoinPoolのアイデアに基づいて、タスクを管理し、定期的なタスクScheduledExecutorServiceを延期します。

ScheduledExecutorService

ExecutorServiceのから継承されます、それは一定期間後に実行または実行することができます。いくつかの遅延や長期サイクルメソッドは、タスクを実行します。サイクルタイムの方法を実行して、新しい方法やScheduledExecutorServiceを提出し、いくつかの遅延や拡張が提出したタスクは、メソッドを設定する場合、このタスクはすぐに実行する必要があること、非正です。

public interface ScheduledExecutorService extends ExecutorService {

    /**
     * 创建延迟任务,在 delay 延迟之后执行,返回一个 ScheduledFuture 表示执行的状态。
     */
    public ScheduledFuture<?> schedule(Runnable command,
                                       long delay, TimeUnit unit);
    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                           long delay, TimeUnit unit);

    /**
     * 创建周期执行的任务,初始延迟之后第一次进行执行,周期时间后重复执行。如果执行的时间超过周期时间也不会同时执行,会有一定的延迟再。返回一个 ScheduledFuture 表示执行的状态。
     */
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);

    /**
     * 创建周期执行的任务,在初始延迟之后第一次执行,在完成之后的 delay 时间后再次执行。返回一个 ScheduledFuture 表示执行的状态。
     */
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit);

}

复制代码

ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutorのはThreadPoolExecutorから継承され、新しく追加された遅延とサイクルアプローチScheduledExecutorServiceを達成します。親クラスのコンストラクタを継承しますが、遅延タスクを実装するために使用DelayedWorkQueueオブジェクトへのタスクリスト。

    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory,
                                       RejectedExecutionHandler handler) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory, handler);
    }
复制代码

keepAliveTimeがゼロに設定され、この方法は、親クラスのコンストラクタThreadPoolExecutorという構成から分かるが、maximumPoolSizeをInteger.MAX_VALUEのセット。corePoolSizeそのような場合は、0に設定すべきではないとallowCoreThreadTimeOutがtrueに設定すべきではない、または新しいタスクが利用可能スレッドではないかもしれないと、スレッド・プールの無駄が生じないという意味スレッドプールを使用することができます。

遅延タスクはやいなや、彼らが有効になっているよりも実行していないが、それらが有効になっている後にするとき、どの程度のリアルタイム保証なしで、彼らが開始されます。

遅延タスクが利用できる前に実行されませんが、何のリアルタイム監視はありません、それは(いくつかの誤りがあるだろう)が利用可能であるとき、それだけで行っていました。タスクの順序を実行するために同時にスケジュール任務、FIFOの原則に基づいて提出されます。タスクは、それが取り消された前に実行され、あなたがsetRemoveOnCancelPolicyが真である設定されていない場合は、唯一のキューの最後まで初期遅延の後に除去されていない場合は設定した後にキャンセルした場合、それを削除します。

タスクがscheduleAtFixedRateとscheduleAtFixedRateプログラムも別のスレッドで実行して、時間的に重複していない連続的に行う、作業前の次の状態は、特定の前の実行、スレッドセーフの結果として始まりました。

ScheduledThreadPoolExecutorのThreadPoolExecutorは、遅延タスクを達成するために適応する方法のいくつかを書き換え、これはあまり説明しません。

ForkJoinPool

提供、ForkJoinTaskタスクを実行提出し、管理し、メソッドの動作を監視するために、スレッドプールのために、AbstractExecutorServiceから継承されます。主に「ワークスチール(ワークスチール)」での一般的なExecutorServiceのとの違いは、アイデア:スレッドプール内のすべてのスレッドがスレッドプールを見つけて実行するためには、タスク生成したスレッドによって実行されるタスクまたはタスクに提出されます。使用ForkJoinPool両方のケースでは、タスクとサブタスクのほとんどは非常に効果的な代替案である実行するために、複数のサブタスクを生成することができます。コンストラクタでasyncModeを設定する場合、タスクは管理のFIFOモードを使用して提出されることはありません、デフォルトでは、ヒープベースのモードを達成することです。しかし、ここではあまり紹介、フォローアップ時間はForkJoinタスクが牙Tengfeiギャングを見ることができるため、これについて書くために専用されます(8)同時話-導入フォーク/参加の枠組み

高速スレッドプール

JavaはnewXxxTreadPool方法としてエグゼキュークラスの形で、すぐにここでは、いくつかの一般的なスレッドプールを確立することができ、私たちの使用のためのスレッドプールの一部をカプセル化したプールに3つの一般的なスレッドです。

  • newFixedThreadPoolは:スレッド数を指定し、corePoolSize maximumPoolSize一貫した、ボーダレスタスクスレッドプールのキューを作成します。
  • newSingleThreadExecutor:単一のワーカースレッド、スレッドプールボーダレスタスクキューを作成します。corePoolSize = maximumPoolSize = 1。
  • newCachedThreadPool:スレッドプールの前に、再利用可能なスレッドを作成します。スレッドがアイドルの前に作成されていない場合は、新しいタスクを使用して破壊されて。同期キューSynchronousQueueを使用します。corePoolSize = 0、maximumPoolSize = Integer.MAX_VALUEで、keepAliveTimeが= 60年代。60年代の新しいタスクがある場合は、以前に作成し、そのスレッドは、それが多重化することができます。
  • newWorkStealingPool:作業盗まForkJoinTaskスレッドプールを生成します。
  • newScheduledThreadPool:遅延、定期的な仕事のスレッドプールのタスクを処理するため。

概要

一般的に十分に明確ThreadPoolExecutorを言えば、スレッドプールを使用する場合は、のScheduledThreadPoolExecutorとForkJoinPoolのための比較的小さな使用のために、特定の状況下で使用され、必要なときに、我々は、そのようなことがあると知っている必要があります仕事でドルができことができると思います。ダグ・リーギャングスターは、これらのスレッドプールのいくつかのデフォルトの実装は、このクラスのメソッドの簡単な使用を直接使用することができますエグゼキュークラスに書き込まれます。

久しぶりの書き込み何かが、何かのリズムではありません、また、不十分な注意次の時間の長さを制御する書き込み。

おすすめ

転載: juejin.im/post/5cf7687de51d4550bf1ae817