第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

具有 corePoolSize 0 的 ThreadPoolExecutor

具有 corePoolSize 0 的 ThreadPoolExecutor

手掌心 2021-09-12 14:26:20
我正在學(xué)習(xí)Java Concurrency In Practice并被困在8.3.1 線程創(chuàng)建和拆卸主題上。以下腳注警告保持corePoolSize零。開發(fā)人員有時會試圖將核心大小設(shè)置為零,這樣工作線程最終會被拆除,因此不會阻止 JVM 退出,但這可能會在不使用SynchronousQueue 用于他們的工作隊列(就像 newCachedThreadPool 一樣)。如果池已經(jīng)達到核心大小,只有在工作隊列已滿時,ThreadPoolExecutor 才會創(chuàng)建新線程。因此,提交到具有任何容量和核心大小為零的工作隊列的線程池的任務(wù)將在隊列填滿之前不會執(zhí)行,這通常不是所期望的。所以為了驗證這一點,我寫了這個程序,它不像上面所說的那樣工作。    final int corePoolSize = 0;    ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,            new LinkedBlockingQueue<>());    // If the pool is already at the core size    if (tp.getPoolSize() == corePoolSize) {        ExecutorService ex = tp;        // So tasks submitted to a thread pool with a work queue that has any capacity        // and a core size of zero will not execute until the queue fills up.        // So, this should not execute until queue fills up.        ex.execute(() -> System.out.println("Hello"));    }輸出: 你好那么,程序的行為是否表明ThreadPoolExecutor如果提交了一個任務(wù)而不管corePoolSize=0. 如果是,那么教科書上的警告是什么。編輯:根據(jù)@SK 的建議測試了jdk1.5.0_22 中的代碼,并進行了以下更改:ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,                new LinkedBlockingQueue<Runnable>(1));//Queue size is set to 1.但是隨著這個變化,程序終止而不打印任何輸出。那么我是否誤解了書中的這些陳述?編輯(@sjlee):很難在評論中添加代碼,所以我將它作為編輯添加在這里...你能嘗試這個修改并針對最新的 JDK 和 JDK 1.5 運行它嗎?final int corePoolSize = 0;ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>());// If the pool is already at the core sizeif (tp.getPoolSize() == corePoolSize) {    ExecutorService ex = tp;    // So tasks submitted to a thread pool with a work queue that has any capacity    // and a core size of zero will not execute until the queue fills up.    // So, this should not execute until queue fills up.    ex.execute(() -> System.out.println("Hello"));}tp.shutdown();if (tp.awaitTermination(1, TimeUnit.SECONDS)) {    System.out.println("thread pool shut down. exiting.");} else {    System.out.println("shutdown timed out. exiting.");}
查看完整描述

3 回答

?
繁花如伊

TA貢獻2012條經(jīng)驗 獲得超12個贊

在 jdk 1.5、1.6、1.7 和 1.8 中運行這個程序時,我發(fā)現(xiàn)ThreadPoolExecutor#execute(Runnable)了 1.5、1.6 和 1.7+ 中的不同實現(xiàn)。這是我發(fā)現(xiàn)的:


JDK 1.5 實現(xiàn)


 //Here poolSize is the number of core threads running.


 public void execute(Runnable command) {

    if (command == null)

        throw new NullPointerException();

    for (;;) {

        if (runState != RUNNING) {

            reject(command);

            return;

        }

        if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))

            return;

        if (workQueue.offer(command))

            return;

        Runnable r = addIfUnderMaximumPoolSize(command);

        if (r == command)

            return;

        if (r == null) {

            reject(command);

            return;

        }

        // else retry

    }

}

當(dāng)corePoolSize為 0 時,此實現(xiàn)不會創(chuàng)建線程,因此不會執(zhí)行提供的任務(wù)。


JDK 1.6 實現(xiàn)


//Here poolSize is the number of core threads running.


  public void execute(Runnable command) {

    if (command == null)

        throw new NullPointerException();

    if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {

        if (runState == RUNNING && workQueue.offer(command)) {

            if (runState != RUNNING || poolSize == 0)

                ensureQueuedTaskHandled(command);

        }

        else if (!addIfUnderMaximumPoolSize(command))

            reject(command); // is shutdown or saturated

    }

}

即使corePoolSize為 0,JDK 1.6 也會創(chuàng)建一個新線程。


JDK 1.7+ 實現(xiàn)(類似于 JDK 1.6,但具有更好的鎖和狀態(tài)檢查)


    public void execute(Runnable command) {

    if (command == null)

        throw new NullPointerException();

    /*

     * Proceed in 3 steps:

     *

     * 1. If fewer than corePoolSize threads are running, try to

     * start a new thread with the given command as its first

     * task.  The call to addWorker atomically checks runState and

     * workerCount, and so prevents false alarms that would add

     * threads when it shouldn't, by returning false.

     *

     * 2. If a task can be successfully queued, then we still need

     * to double-check whether we should have added a thread

     * (because existing ones died since last checking) or that

     * the pool shut down since entry into this method. So we

     * recheck state and if necessary roll back the enqueuing if

     * stopped, or start a new thread if there are none.

     *

     * 3. If we cannot queue task, then we try to add a new

     * thread.  If it fails, we know we are shut down or saturated

     * and so reject the task.

     */

    int c = ctl.get();

    if (workerCountOf(c) < corePoolSize) {

        if (addWorker(command, true))

            return;

        c = ctl.get();

    }

    if (isRunning(c) && workQueue.offer(command)) {

        int recheck = ctl.get();

        if (! isRunning(recheck) && remove(command))

            reject(command);

        else if (workerCountOf(recheck) == 0)

            addWorker(null, false);

    }

    else if (!addWorker(command, false))

        reject(command);

}

即使corePoolSize是 0,JDK 1.7 也會創(chuàng)建一個新線程。


因此,corePoolSize=0在 JDK 1.5 和 JDK 1.6+ 的每個版本中,這似乎都是一個特例。


但奇怪的是,書中的解釋與任何程序結(jié)果都不符。


查看完整回答
反對 回復(fù) 2021-09-12
?
MMMHUHU

TA貢獻1834條經(jīng)驗 獲得超8個贊

似乎這是舊 Java 版本的錯誤,但現(xiàn)在在 Java 1.8 中不存在。


根據(jù)來自的 Java 1.8 文檔ThreadPoolExecutor.execute():


     /*

     * Proceed in 3 steps:

     *

     * 1. If fewer than corePoolSize threads are running, try to

     * start a new thread with the given command as its first

     * task.  The call to addWorker atomically checks runState and

     * workerCount, and so prevents false alarms that would add

     * threads when it shouldn't, by returning false.

     *

     * 2. If a task can be successfully queued, then we still need

     * to double-check whether we should have added a thread

     * (because existing ones died since last checking) or that

     * the pool shut down since entry into this method. So we

     * recheck state and if necessary roll back the enqueuing if

     * stopped, or start a new thread if there are none.

     * ....

     */

第二點,在加入一個worker到隊列后,再檢查一下,如果不是排隊任務(wù),可以啟動一個新線程,而不是回滾入隊并啟動一個新線程。


這就是正在發(fā)生的事情。在第一次檢查期間,任務(wù)已排隊,但在重新檢查期間,將啟動一個新線程來執(zhí)行您的任務(wù)。


查看完整回答
反對 回復(fù) 2021-09-12
  • 3 回答
  • 0 關(guān)注
  • 246 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號