(ソースコードを見るために横画面電話がより便利です)
注意:Javaソースコード解析部を特別な命令がjava8バージョンに基づいてされていない場合。
簡単な紹介
ThreadPoolExecutorの施工方法は、一連の問題を誘発することができ、比較的単純な、しかし非常に有益なものの、同じように、これは多くの場合、面接で聞かれる質問で、トンの弟がすぐ下に記載されている、スレッドプールの入り口を作成することですあなたがそれに答えることができればThreadPoolExecutorの工法上の問題の一部は、あなたは下記の分析を参照することはできません。
問題
(1)ThreadPoolExecutorいくつかの施工方法がありますか?
(2)ThreadPoolExecutor最長の構築方法は、いくつかのパラメータを持っていますか?
(3)keepAliveTimeが、何をどうするのですか?
(7)コアスレッドが近くにタイムアウトしませんか?あなたは残業閉じことができますか?
(4)ConcurrentLinkedQueueは、タスクキューのパラメータとして使用することはできませんか?
(5)デフォルトのスレッドが作成されますか?
(6)独自のスレッドファクトリを実装する方法?
(7)を拒否した戦略は何ですか?
(8)拒否のデフォルトの戦略とは何ですか?
コンストラクタ
さて、私たちに直接コードに。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
ThreadPoolExecutor 4つのコンストラクタの最初の3つは、最終的に7つのパラメータ、すなわちcorePoolSize、maximumPoolSize、keepAliveTimeが、ユニット、ワークキュー、threadFactory、ハンドラを持っている最後の呼び出し、です。
corePoolSize
スレッドのコア数。
スレッドのコアの数よりも少ないを実行しているスレッドの数、タスクは、カーネルスレッドを作成する際に、
場合スレッドのコア数以上実行しているスレッドの数は、最初のタスクは、スレッドを作成することではなく、タスクキューに投入します。
maximumPoolSize
スレッドの最大数。
タスクキューが満杯になると、番号から公共の論文はオリジナルの「トンの弟は、ソースを読んで」、非コアタスクにスレッドを作成することでしたが、スレッドの最大数を超えることはできません。
keepAliveTimeが+ユニット
スレッドは、アイドル時間と単位のまま。
デフォルトでは、このパラメータは、2つのスレッドが唯一の非コア・スレッドのため、すなわち、有効なスレッドのコアの数よりも多い動作している場合。
しかし、場合allowCoreThreadTimeOutは、コアスレッドに対して有効にも、trueに設定されて。
すなわち、タスクキューが空である場合、スレッドは、主にタイムアウトポーリング(タイムアウト、単位)を達成するための方法で内部キューを遮断することによって、それが破壊されるどのくらいのままです。
ワークキュー
タスクキュー。
スレッドのコア数以上実行しているスレッドの数は、タスクがタスクキューに来るときです。
それは安全な同時キューであるが、ので、それは、引数としてConcurrentLinkedQueueのようではないが、それはブロッキングキューではありませんので、このキューは、キューをブロックしなければなりません。
// ConcurrentLinkedQueue并没有实现BlockingQueue接口
public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
implements Queue<E>, java.io.Serializable {
// ...,本文由公从号“彤哥读源码”原创
}
threadFactory
スレッドファクトリ。
デフォルトでは、スレッドの欠点名が自動的に生成作成されてい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;
}
}
どのようにカスタムスレッドファクトリそれですか?
実際には、非常に単純な、ThreadFactoryの独自の実現、そして名前とそれに渡されたコンストラクタパラメータとしてデーモンかどうか。
興味のある学生は、Googleや糸工場のデフォルトのスレッド工場ネッティーを参照することができます。
io.netty.util.concurrent.DefaultThreadFactory
com.google.common.util.concurrent.ThreadFactoryBuilder
ハンドラ
拒否ポリシー。
拒否した戦略は、タスクキューがいっぱいになると、スレッドの最大数に達した、と新しいタスクを追加するには、この時間のとき、スレッドプールが処理されるべきロジックによってこれらの新しいタスクを負担することができなかったことを意味します。
一般的に使用される戦略は、現在のタスクを破棄最古のタスクを破棄し、例外をスローし、自分自身の呼び出し元が待機して対処することを拒否してきました。
デフォルトの戦略は、例外がスローされます、タスクを追加し、スレッドプール、その後、入力された発信者を運ぶことができない例外をスローすることを拒否することです。
デフォルトでは、ポリシーを否定する彼らは、この例外た後、第2の治療をキャッチすることができ、少なくとも、発信者、明らかにはるかに優れた、比較的単純で、粗が、廃棄タスクポリシーに相対的です。
卵
OK、我々は今日で深さの分析を行い、この工法のThreadPoolExecutor、これは、あなたはどのような質問にについて持っているのですか?トンの弟が議論ささやくへようこそ。