Javaのクラスライブラリ同時スレッドプール

新しいスレッドの医療過誤

  • 頻繁にスレッドを作成し、スレッドが時間を必要とする破壊するために、大幅にシステムの効率を低下させます
  • 一元管理の欠如は、新しいオブジェクトは、無制限のかもしれあまりにも多くのシステムリソースを占有で、その結果、互いに競合します
  • より定期的に実行され、実行の欠如、スレッドを中断し、はるかに

利点のスレッドプール

  • スレッドを再利用することができ、スレッドを作成し、破壊の数を減少させる、複数のタスクを実行することができ
  • システムリソースの使用率を向上同時制御の最大数、
  • リソースのための過当競争を避けるため、ブロックを避けます
  • 定期的に提供し、シングルスレッド、同時制御やその他の機能

スレッドプールのライフサイクル

スレッドプールのライフサイクル

ThreadPoolExecutorのコアクラス


public class ThreadPoolExecutor extends AbstractExecutorService {

    // 包含 4 个构造方法。 其他 3 个通过调用该构造方法。

    public ThreadPoolExecutor(
        int corePoolSize,                       // 核心线程数量
        int maximumPoolSize,                   // 最大线程数
        long keepAliveTime,                    // 线程没有执行任务时最大保持多久终止
        TimeUnit unit,                         // keepAliveTime的时间单位
        BlockingQueue<Runnable> workQueue,     // 阻塞队列,存储等待执行的任务
        ThreadFactory threadFactory,           // 线程工厂,用来创建线程
        RejectedExecutionHandler handler       // 当拒绝处理任务时的策略
    ) { }

}
复制代码

コア引数のコンストラクタ

int型corePoolSize

スレッドのコア数。

スレッドプール内のスレッドの数がcorePoolSizeに達したときにデフォルトした後、スレッドプールを作成し、スレッドプール内のスレッド数が0である、後で、それはタスクを実行するスレッドを作成しますするタスクがあるとき、の到着となりますキャッシュキュー(ワークキュー)それらへの使命。

int型maximumPoolSize

スレッドの最大数。スレッドプール内のスレッド数の最大値を作成します。

int型keepAliveTimeが

長いスレッドの終了デューティを維持するために上限はありません。

デフォルトでは、ときにのみcorePoolSizeよりも大きなスレッドプール内のスレッドの数は、keepAliveTimeがが動作します。

スレッドプール内のスレッドの数がゼロになるまでallowCoreThreadTimeOut(boolean)メソッドを呼び出して、スレッドプール内のスレッドの数がcorePoolSize以上でないとき、keepAliveTimeがパラメータが遊びに来ます。

TimeUnitでユニット

パラメータkeepAliveTimeが時間単位

TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒
复制代码

BlockingQueueのワークキュー

タスクが保存されて実行されるのを待って、待ち行列をブロックし、実行するためのプロセス・スレッド・プールに重大な影響を与えます。

  • ArrayBlockingQueue
  • LinkedBlockingQueue
  • SynchronousQueue

threadFactory threadFactory

スレッドファクトリは、メインスレッドを作成するために使用されます。

RejectedExecutionHandlerハンドラ

戦略は、ときにタスクを処理することを拒否した場合。

// 丢弃任务,并抛出 RejectedExecutionException
ThreadPoolExecutor.AbortPolicy
// 丢弃任务,不抛出异常
ThreadPoolExecutor.DiscardPolicy
// 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.DiscardOldestPolicy
// 调用线程处理该任务
ThreadPoolExecutor.CallerRunsPolicy
复制代码

内部業務プロセスとの相互作用のスレッドプールのスレッドプール

内部業務プロセスとの相互作用のスレッドプールのスレッドプール

ThreadPoolExecutor一般的な方法

public class ThreadPoolExecutor extends AbstractExecutorService {
    // 提交任务,交给线程池执行
    public void execute(Runnable command) {}

    // 提交任务,能够返回执行结果 (execute + Future)
    public Future<?> submit(Runnable task) {}
    public <T> Future<T> submit(Runnable task, T result) {}
    public <T> Future<T> submit(Callable<T> task) {}

    // 关闭线程池,等待任务执行完
    public void shutdown() {}
            
    // 立即关闭,不等待任务关闭        
    public void shutdownNow() {}

    // 获得线程池中已执行和未执行的任务总数
    public long getTaskCount() {}

    // 获得已完成任务数量
    public long getCompletedTaskCount() {}

    // 线程池当前的线程数量
    public int getPoolSize() {}

    // 获得当前线程池中正在执行的线程数量
    public int getActiveCount() {
}
复制代码

内蔵のスレッドプール


  • newSingleThreadExecutor()
  • newFixedThreadPooll(int型にnthreads)
  • newCachedThreadPool()
  • newScheduledThreadPool(int型corePoolSize)/ newSingleThreadScheduledExecutor()
  • newWorkStealingPool(int型の並列処理)

提供される汎用スレッドプールエグゼキュータとスレッドプールの異なる構成を作成するための作成方法は、主な違いは、異なるタイプまたは異なるExecutorServiceの初期パラメータです。

スレッドプールのクラス図

newSingleThreadExecutor()

  • シングルスレッドのスレッドプールを作成します
  • タスクの順序に従って提出された実行順序のすべてのタスクの実施を確保するための作業に1つだけのスレッド
  • ほとんどの既存のプログラムは、シングルスレッドのGUIです
  • Androidのは、バッチ・アプリケーションは、アプリケーションのボリュームが同時IOの邪魔には適していません削除してもインストールされているシングルスレッドのデータベース操作、ファイル操作で使用することができ、応答性のUIスレッドの動作に影響を与える可能性があります
public static void main(String[] args) {

    ExecutorService pool = Executors.newSingleThreadExecutor();

    // 执行过程将会顺序输出 0 --> 9
    for (int i = 0; i < 10; i++) {
        final int index = i;
        executorService.execute(() -> {
            System.out.println(index);
        })
    }
}
复制代码
// corePoolSize = 1
// maximumPoolSIze = 1
// keyAliveTime = 0L
// unit = TimeUnit.MILLISECONDS
// workQueue = new LinkedBlockingQueue<Runnable>()
// threadFactory = Executors.defaultThreadFactory()
// handler = defaultHandler = new AbortPolicy()
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
复制代码

newFixedThreadPooll(int型にnthreads)

  • 固定サイズのスレッドプールを作成し、それぞれの時間は、あなたはそれがnthreadsの値に到達するまでスレッドを作成するタスクを送信します
  • スレッドの実行異常終了すると、新しいスレッドプールのスレッドを追加しますので、彼らはnthreadsの値に達すると、スレッドプールのサイズは、変更されません
  • 同時スレッドの最大数を制御することができ、余分なスレッドは、キュー内で待機します
public static void main(String[] args) {
    // 线程池大小为3
    ExecutorService executorService = Executors.newFixedThreadPool(3);

    // 每隔秒打印三个数字
    for (int i = 0; i < 50; i++) {
        final int index = i;
        executorService.execute(() -> {
            System.out.println(index);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    executorService.shutdown();
}
复制代码
// corePoolSize = nThreads
// maximumPoolSIze = nThreads
// keyAliveTime = 0L
// unit = TimeUnit.MILLISECONDS
// workQueue = new LinkedBlockingQueue<Runnable>()
// threadFactory = Executors.defaultThreadFactory()
// handler = defaultHandler = new AbortPolicy()
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
            0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
复制代码

newCachedThreadPool()

  • キャッシュされたスレッドプールを作成します。
  • スレッドプールのスレッドのサイズが必要な処理タスクを超えて、それがスレッドを部分的に自由に(60年代)を回収します
  • タスクの数を増やす場合は、このスレッドプールは、インテリジェンスのタスクを処理するために新しいスレッドを追加することができます
  • このスレッドプールは、スレッドプールのサイズを制限しない、スレッドプールスレッドの最大サイズは、作成することができ、オペレーティング・システム(またはJVM)のサイズに完全に依存します
public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();

    for (int i = 0; i < 10; i++) {
        final int index = i;
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(index);
            }
        });
    }

    executorService.shuntdown();
}
复制代码
// corePoolSize = 0
// maximumPoolSIze = Integer.MAX_VALUE
// keyAliveTime = 60L
// unit = TimeUnit.MILLISECONDS
// workQueue = new LinkedBlockingQueue<Runnable>()
// threadFactory = Executors.defaultThreadFactory()
// handler = defaultHandler = new AbortPolicy()
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
                                new SynchronousQueue<Runnable>());
}
复制代码

newScheduledThreadPool(int型corePoolSize)/ newSingleThreadScheduledExecutor()

  • スレッドプールのサイズ制限を作成します。
  • 定期的かつ定期的なタスクの需要のサポート
public static void main(String[] args) {
    // new ScheduledThreadPoolExecutor(corePoolSize)
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);

    // executorService 执行具有调度含义
    // delay: 3  SECONDS 后执行
	executorService.schedule(() -> System.out.println("schedule running"), 2, TimeUnit.SECONDS);

    executorService.shutdown();
}
复制代码
public static void main(String[] args) {
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
    
    // executorService 执行具有调度含义
    // scheduleAtFixedRate 以指定的速率运行 每隔一段时候就触发
    // 1: initalDelay 延迟1秒
    // 3: period 每格3秒
    executorService.scheduleAtFixedRate(() -> System.out.println(System.nanoTime()), 1, 3, TimeUnit.SECONDS);

    // 不适用关闭线程池
    // 若需要关闭线程池,可通过提供关闭信息,再调用该方法
    // executorService.shutdown();
}
复制代码
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

// --- 

// DEFAULT_KEEPALIVE_MILLIS = 10L
// MILLISECONDS = TimeUnit.MILLI_SCALE
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE,
            DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
            new DelayedWorkQueue());
}
复制代码

newWorkStealingPool(int型の並列処理)

Javaの8内部ForkJoinPool、ワークスチール・アルゴリズム、並列処理タスク(デフォルトは使用可能なホストのCPUコアの数である)の使用を構築する方法を作成するには、これを追加する前に、処理の順序を保証するものではありません。

public static ExecutorService newWorkStealingPool() {
        return new ForkJoinPool
            (Runtime.getRuntime().availableProcessors(),
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
}

// --- 

public ForkJoinPool(int parallelism,
                        ForkJoinWorkerThreadFactory factory,
                        UncaughtExceptionHandler handler,
                        boolean asyncMode) {

    this(checkParallelism(parallelism),
            checkFactory(factory),
            handler,
            asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
            "ForkJoinPool-" + nextPoolId() + "-worker-");

    checkPermission();
}
复制代码

スレッドプールを設定します


私たちは、より実用的な状況を必要としています。

  • CPU集約型のタスク

CPUは、できるだけ多くを絞る必要があります。参照は、N / N + 1であってもよい(N:CPUの数)

  • IO集約型

= CPUは、スレッドの数監査役×(1 +平均待ち時間/平均作業時間)を参照することができます

参考読書


www.cnblogs.com/kuoAT/p/671...

www.cnblogs.com/dolphin0520...

おすすめ

転載: juejin.im/post/5d4d289051882515fd6bd519