Javaの同時実行スレッドプールのプロフィール
なぜ我々は、スレッドプールを使用する必要がありますか?
私たちは、私たちそれぞれがプログラムを実行するスレッドを作成、スレッドは比較的高価な資源であることを知って、実際には、オペレーティング・システムは、私たちの使命を遂行するために相応のスレッドを作成し、我々は頻繁に作成し、スレッドがシステムリソースを消費している破壊します同時の小さな数は、システムにはほとんど影響のようですが、同時多数の、私たちは要求ごとにスレッドを作成する必要がある場合は、タスク、その後破壊され、そう頻繁に作成を実行し、スケジュールするのを待つとき、破壊スレッドはシステムリソースを消費しています。
そして、我々は、スレッドプールのスレッドが再利用しますので、この損失を低減するために非常に良いことができ、スレッドを管理するスレッドプールを使用し、再利用スレッドは何のことでしょうか?どのスレッドプールのスレッドで、タスクスレッドが終わっ実行した後ではない私たち自身は、のような、単一のタスクを実行するためにスレッドを作成し、プール内のスレッドは、その実行ロジックがありwhile
、このサイクルをwhile
サイクル並行性の高い環境であれば、スレッドが大幅にシステムリソースを節約し、操作するスレッドの作成と破棄を減らすなる、(状況下での作業があります)タスクを取得してから実行していきます。
のは、スレッドプールのソースコードの一部を見てみましょう:
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
Repeatedly gets tasks from queue and executes them
これは、上記のコメントの方法であり、かつコード方式からのコメント、スレッドプールのスレッドは、その後、以上ですが、タスクを取得するためのイニシアチブ(リピート)がかかりますタスクを実行していない非常に明確に示します実行。
スレッドプールの設計
それははっきりインタフェースを指向プログラミングされます。
いくつかの属性スレッドプール
ここで図と組み合わせたソースコードと、これらの属性のコメントは、理解することは難しいことではありませんです。
/**
* Core pool size is the minimum number of workers to keep alive
* (and not allow to time out etc) unless allowCoreThreadTimeOut
* is set, in which case the minimum is zero.
*/
private volatile int corePoolSize;
/**
* Maximum pool size. Note that the actual maximum is internally
* bounded by CAPACITY.
*/
private volatile int maximumPoolSize;
/**
* Timeout in nanoseconds for idle threads waiting for work.
* Threads use this timeout when there are more than corePoolSize
* present or if allowCoreThreadTimeOut. Otherwise they wait
* forever for new work.
*/
private volatile long keepAliveTime;
/**
* The queue used for holding tasks and handing off to worker
* threads. We do not require that workQueue.poll() returning
* null necessarily means that workQueue.isEmpty(), so rely
* solely on isEmpty to see if the queue is empty (which we must
* do for example when deciding whether to transition from
* SHUTDOWN to TIDYING). This accommodates special-purpose
* queues such as DelayQueues for which poll() is allowed to
* return null even if it may later return non-null when delays
* expire.
*/
private final BlockingQueue<Runnable> workQueue;
/**
* Factory for new threads. All threads are created using this
* factory (via method addWorker). All callers must be prepared
* for addWorker to fail, which may reflect a system or user's
* policy limiting the number of threads. Even though it is not
* treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in
* the queue.
*
* We go further and preserve pool invariants even in the face of
* errors such as OutOfMemoryError, that might be thrown while
* trying to create threads. Such errors are rather common due to
* the need to allocate a native stack in Thread.start, and users
* will want to perform clean pool shutdown to clean up. There
* will likely be enough memory available for the cleanup code to
* complete without encountering yet another OutOfMemoryError.
*/
private volatile ThreadFactory threadFactory;
/**
* Handler called when saturated or shutdown in execute.
*/
private volatile RejectedExecutionHandler handler;
スレッドプール構造の
スレッドプールは、スレッドを作成します
この図は、中国では、非常に鮮やかであるべきである、とあなたはそれを説明する必要はありません。
拒否されたスレッドプールのタスク
スレッドプールのタスクキューがいっぱいになると、新しいスレッド(到達したスレッドの数を作成できない場合maximumPoolSize
)、スレッドプールは、タスクを拒否します。実際には、他の状況のスレッドプールは、ここでのタスクは誰もが知っているように、単純で拒否されますがあり、スレッドプールは、タスクを拒否します。
ここでは、Javaスレッド・プールの一般的な理解を持っており、詳細な原理を説明していない、すべての後に、また初心者のブロガーを、さらに補足する機会を持つことをちょうどそうです。