JAVA同時-Executor

構造

クラス継承グラフ:

clipboard.png

各インターフェース/クラスの上記の関係及び機能:

  1. エグゼキュータ
    の使命とタスクとは別のアクチュエータインタフェース、だけでなく、最上位の抽象コア・インタフェース、。
  2. ExecutorServiceのは
    執行、非同期タスクの実行能力に基づいてアクチュエータのライフサイクル管理を提供します。
  3. ScheduledExecutorServiceは
    ExecutorServiceのベースで行われ、実行/サイクル・タスクを遅らせるための機能を提供します。
  4. エグゼキュータは、
    特定のアクチュエータ静的工場を生成します
  5. ThreadFactory
    シングルスレッドの作成に使用するスレッドファクトリ植物の特性を再利用することができながら、スレッドは、面倒な手作業を軽減するために作成されます。
  6. AbstractExecutorService
    ExecutorServiceの抽象実装では、アクチュエータのクラスのすべてのタイプの実現のための基礎を提供します。
  7. ThreadPoolExecutor
    スレッドプールエグゼキュータは、スレッドプールのスレッドを管理することができ、最も一般的に使用されるエグゼキュータです。
  8. ScheduledThreadPoolExecutorの
    ThreadPoolExecutorでは、タスクスケジューリングサイクルの増加のサポートに基づきます。
  9. ForkJoinPool
    フォーク/フォーク/参加フレームワークのコアクラスを実装する際に、JDK1.7を導入したスレッドプールを、参加します。

ThreadPoolExecutor

スレッドファクトリ

あなたはThreadFactoryを指定しない場合は作成するときにThreadPoolExecutor、デフォルトで使用されExecutors.defaultThreadFactory()、すなわちExecutors.DefaultThreadFactory、ThreadFactoryを作成します。

public static ThreadFactory defaultThreadFactory() {
    return new DefaultThreadFactory();
}

/**
 * 默认的线程工厂.
 */
static class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;
 
    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
    }
 
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

ワーカースレッドプールのタスクスレッド

private final class Worker
    extends AbstractQueuedSynchronizer
    implements Runnable
{
    private static final long serialVersionUID = 6138294804551838833L;
    // 这个是真正的线程,任务靠你啦
    final Thread thread;
    // 前面说了,这里的 Runnable 是任务。为什么叫 firstTask?因为在创建线程的时候,如果同时指定了
    // 这个线程起来以后需要执行的第一个任务,那么第一个任务就是存放在这里的(线程可不止执行这一个任务)
    // 当然了,也可以为 null,这样线程起来了,自己到任务队列(BlockingQueue)中取任务(getTask 方法)就行了
    Runnable firstTask;
    // 用于存放此线程完成的任务数,注意了,这里用了 volatile,保证可见性
    volatile long completedTasks;
    // Worker 只有这一个构造方法,传入 firstTask,也可以传 null
    Worker(Runnable firstTask) {
        setState(-1); // inhibit interrupts until runWorker
        this.firstTask = firstTask;
        // 调用 ThreadFactory 来创建一个新的线程
        this.thread = getThreadFactory().newThread(this);
    }
    // 这里调用了外部类的 runWorker 方法
    public void run() {
        runWorker(this);
    }
    ...// 其他几个方法没什么好看的,就是用 AQS 操作,来获取这个线程的执行权,用了独占锁
}

特に注目は、ここでは初期化されますthis 任务分配给了线程スレッド,后面调用线程を起動,即调用労働者は中的法をrun`。

注意点

2つのオブジェクトを注意することは、ソースコードを参照してください。

タスクキューBlockingQueue<Runnable> workQueue

これは、タスクスレッドのコレクションですHashSet<Worker> workers

プロセス・スレッド・プールの進捗状況

  • ワーカースレッドの数に等しい未満のcorePoolSizeタスクは、firstTaskパッケージ化worker、およびに追加worker

  • ワーカースレッドの数よりも大きいcorePoolSizeと、キューに入れることができ、ここでのタスクはなりcommandにチームworkQueue
    • そこ特別なポイントであるaddWorker(null, false)、これはその後、追加ワーカースレッド、追加することで、ここでは、チームにタスクを防ぐためであるが、0にワーカースレッドfirstTaskしますnullworkerworkers
  • workQueueキューがいっぱいです、未満maximumPoolSize再び、タスクfirstTaskパッケージworkerに、コメントを追加しましたworkers

上記のfirstTaskパッケージworkerとして、workerスレッドが開始されると、スピンがタスクの処理を停止し、最初のプロセスがあるworkerfirstTaskあれば、firstTaskプロセスが終了するかされfirstTaskているnullそして呼び出すために続けて、getTaskキューからのメソッドworkQueueのGETタスク処理を。

参考:

高度なJavaのマルチスレッド(三〇から九) - JUCの執行体制:執行フレームワークの概要

Javaのスレッドプールの設計とソースコードの実装の深さの解釈

おすすめ

転載: www.cnblogs.com/hongdada/p/11983483.html