Javaの同時実行スレッドプールのプロフィール

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スレッド・プールの一般的な理解を持っており、詳細な原理を説明していない、すべての後に、また初心者のブロガーを、さらに補足する機会を持つことをちょうどそうです。

公開された302元の記事 ウォンの賞賛435 ビュー710 000 +

おすすめ

転載: blog.csdn.net/qq_37960603/article/details/104334254