成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

五種判斷線程池任務(wù)執(zhí)行完成的方式

開發(fā) 前端
shutdown() :對線程池進(jìn)行有序關(guān)閉。調(diào)用該方法后,線程池將不再接受新的任務(wù),但會繼續(xù)執(zhí)行已提交的任務(wù)。如果線程池已經(jīng)處于關(guān)閉狀態(tài),則對該方法的調(diào)用沒有額外的作用。

Thread線程是否執(zhí)行完成,我們可以調(diào)用join方法然后等待線程執(zhí)行完成;那在使用線程池的時候,我們?nèi)绾沃谰€程已經(jīng)執(zhí)行完成了?本文就帶給大家五種判斷的方式:

  • isTerminated() 方式,在執(zhí)行 shutdown() ,關(guān)閉線程池后,判斷是否所有任務(wù)已經(jīng)完成。
  • ThreadPoolExecutor 的 getCompletedTaskCount() 方法,判斷完成任務(wù)數(shù)和全部任務(wù)數(shù)是否相等。
  • CountDownLatch計數(shù)器,使用閉鎖計數(shù)來判斷是否全部完成。
  • 手動維護(hù)一個公共計數(shù) ,原理和閉鎖類似,就是更加靈活。
  • 使用submit向線程池提交任務(wù),F(xiàn)uture判斷任務(wù)執(zhí)行狀態(tài)。

方法一:isTerminated()

測試代碼

package pool;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 百里
 */
public class BaiLiIsShutdownThreadPoolDemo {
    /**
     * 創(chuàng)建一個最大線程數(shù)15的線程池
     */
    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10,
            15,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(10));
    /**
     * 線程執(zhí)行方法,隨機(jī)等待0到10秒
     */
    private static void sleepMethod(int index){
        try {
            long sleepTime = new Double(Math.random() * 10000).longValue();
            Thread.sleep(sleepTime);
            System.out.println("當(dāng)前線程執(zhí)行結(jié)束: " + index);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法一:isTerminated
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> sleepMethod(index));
        }
        pool.shutdown();
        while (!pool.isTerminated()){
            Thread.sleep(1000);
            System.out.println("還沒停止。。。");
        }
        System.out.println("全部執(zhí)行完畢");
    }
}

上述代碼處理邏輯在主線程中進(jìn)行循環(huán)判斷,全部任務(wù)是否已經(jīng)完成。

這里有兩個主要方法:

  • shutdown() :對線程池進(jìn)行有序關(guān)閉。調(diào)用該方法后,線程池將不再接受新的任務(wù),但會繼續(xù)執(zhí)行已提交的任務(wù)。如果線程池已經(jīng)處于關(guān)閉狀態(tài),則對該方法的調(diào)用沒有額外的作用。
  • isTerminated() :判斷線程池中的所有任務(wù)是否在關(guān)閉后完成。只有在調(diào)用了shutdown()或shutdownNow()方法后,所有任務(wù)執(zhí)行完畢,才會返回true。需要注意的是,在調(diào)用shutdown()之前調(diào)用isTerminated()方法始終返回false。

優(yōu)缺點分析

優(yōu)點 :操作簡單。
缺點 :需要關(guān)閉線程池。并且日常使用是將線程池注入到Spring容器,然后各個組件中統(tǒng)一用同一個線程池,不能直接關(guān)閉線程池。

方法二:getCompletedTaskCount()

測試代碼

package pool;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 百里
 */
public class BaiLiIsShutdownThreadPoolDemo {
    /**
     * 創(chuàng)建一個最大線程數(shù)15的線程池
     */
    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10,
            15,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(10));
    /**
     * 線程執(zhí)行方法,隨機(jī)等待0到10秒
     */
    private static void sleepMethod(int index){
        try {
            long sleepTime = new Double(Math.random() * 10000).longValue();
            Thread.sleep(sleepTime);
            System.out.println("當(dāng)前線程執(zhí)行結(jié)束: " + index);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法二:getCompletedTaskCount
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> sleepMethod(index));
        }
        //當(dāng)線程池完成的線程數(shù)等于線程池中的總線程數(shù)
        while (!(pool.getTaskCount() == pool.getCompletedTaskCount())) {
            System.out.println("任務(wù)總數(shù):" + pool.getTaskCount() + "; 已經(jīng)完成任務(wù)數(shù):" + pool.getCompletedTaskCount());
            Thread.sleep(1000);
            System.out.println("還沒停止。。。");
        }
        System.out.println("全部執(zhí)行完畢");
    }
}

上述代碼處理邏輯還是一樣在主線程循環(huán)判斷,主要就兩個方法:

  • getTaskCount() :返回計劃執(zhí)行的任務(wù)總數(shù)。由于任務(wù)和線程的狀態(tài)可能在計算過程中動態(tài)變化,返回的值只是一個近似值。這個方法返回的是線程池提交的任務(wù)總數(shù),包括已經(jīng)完成和正在執(zhí)行中的任務(wù)。
  • getCompletedTaskCount() :返回已經(jīng)完成執(zhí)行的任務(wù)的大致總數(shù)。由于任務(wù)和線程的狀態(tài)可能在計算過程中動態(tài)改變,返回的值只是一個近似值,并且在連續(xù)的調(diào)用中不會減少。這個方法返回的是已經(jīng)完成執(zhí)行的任務(wù)數(shù)量,不包括正在執(zhí)行中的任務(wù)。

優(yōu)缺點分析

  • 優(yōu)點 :不必關(guān)閉線程池,避免了創(chuàng)建和銷毀帶來的損耗。
  • 缺點 :使用這種判斷存在很大的限制條件;必須確定在循環(huán)判斷過程中沒有新的任務(wù)產(chǎn)生。

方法三:CountDownLatch

測試代碼

package pool;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 百里
 */
public class BaiLiIsShutdownThreadPoolDemo {
    /**
     * 創(chuàng)建一個最大線程數(shù)15的線程池
     */
    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10,
            15,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(10));
    /**
     * 線程執(zhí)行方法,隨機(jī)等待0到10秒
     */
    private static void sleepMethod(int index){
        try {
            long sleepTime = new Double(Math.random() * 10000).longValue();
            Thread.sleep(sleepTime);
            System.out.println("當(dāng)前線程執(zhí)行結(jié)束: " + index);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法三:CountDownLatch
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        //計數(shù)器,判斷線程是否執(zhí)行結(jié)束
        CountDownLatch taskLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> {
                sleepMethod(index);
                taskLatch.countDown();
                System.out.println("當(dāng)前計數(shù)器數(shù)量:" + taskLatch.getCount());
            });
        }
        //當(dāng)前線程阻塞,等待計數(shù)器置為0
        taskLatch.await();
        System.out.println("全部執(zhí)行完畢");
    }
}

優(yōu)缺點分析

優(yōu)點 :代碼優(yōu)雅,不需要對線程池進(jìn)行操作。
缺點 :需要提前知道線程數(shù)量;性能較差;還需要在線程代碼塊內(nèi)加上異常判斷,否則在 countDown之前發(fā)生異常而沒有處理,就會導(dǎo)致主線程永遠(yuǎn)阻塞在 await。

方法四:公共計數(shù)

測試代碼

package pool;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 百里
 */
public class BaiLiIsShutdownThreadPoolDemo {
    /**
     * 創(chuàng)建一個最大線程數(shù)15的線程池
     */
    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10,
            15,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(10));
    /**
     * 線程執(zhí)行方法,隨機(jī)等待0到10秒
     */
    private static void sleepMethod(int index){
        try {
            long sleepTime = new Double(Math.random() * 10000).longValue();
            Thread.sleep(sleepTime);
            System.out.println("當(dāng)前線程執(zhí)行結(jié)束: " + index);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static int taskNum = 0; //計數(shù)器

    /**
     * 方法四:公共計數(shù)
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Lock lock = new ReentrantLock();
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> {
                sleepMethod(index);
                lock.lock();
                taskNum++;
                lock.unlock();
            });
        }
        while(taskNum < 10) {
            Thread.sleep(1000);
            System.out.println("還沒停止。。。當(dāng)前完成任務(wù)數(shù):" + taskNum);
        }
        System.out.println("全部執(zhí)行完畢");
    }
}

這種實現(xiàn)其實就是通過加鎖計數(shù),然后循環(huán)判斷。

優(yōu)缺點分析

  • 優(yōu)點 :手動維護(hù)方式更加靈活,對于一些特殊場景可以手動處理。
  • 缺點 :和CountDownLatch相比,一樣需要知道線程數(shù)目,但是代碼實現(xiàn)比較麻煩。

方法五:Future

測試代碼

package pool;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 百里
 */
public class BaiLiIsShutdownThreadPoolDemo {
    /**
     * 創(chuàng)建一個最大線程數(shù)15的線程池
     */
    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10,
            15,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(10));
    /**
     * 線程執(zhí)行方法,隨機(jī)等待0到10秒
     */
    private static void sleepMethod(int index){
        try {
            long sleepTime = new Double(Math.random() * 10000).longValue();
            Thread.sleep(sleepTime);
            System.out.println("當(dāng)前線程執(zhí)行結(jié)束: " + index);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法五:Future
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Future future = pool.submit(() -> sleepMethod(1));
        while (!future.isDone()){
            Thread.sleep(1000);
            System.out.println("還沒停止。。。");
        }
        System.out.println("全部執(zhí)行完畢");
    }
}

優(yōu)缺點分析

優(yōu)點:使用簡單,不需要關(guān)閉線程池。

缺點:每個提交給線程池的任務(wù)都會關(guān)聯(lián)一個Future對象,這可能會引入額外的內(nèi)存開銷。如果需要處理大量的任務(wù),可能會占用較多的內(nèi)存。

測試代碼匯總

package pool;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 五種判斷線程池任務(wù)執(zhí)行完成的方式
 * @author 百里
 */
public class BaiLiIsShutdownThreadPoolDemo {
    /**
     * 創(chuàng)建一個最大線程數(shù)15的線程池
     */
    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10,
            15,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(10));
    /**
     * 線程執(zhí)行方法,隨機(jī)等待0到10秒
     */
    private static void sleepMethod(int index){
        try {
            long sleepTime = new Double(Math.random() * 10000).longValue();
            Thread.sleep(sleepTime);
            System.out.println("當(dāng)前線程執(zhí)行結(jié)束: " + index);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法一:isTerminated
     * @param args
     * @throws InterruptedException
     */
    public static void isTerminatedTest(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> sleepMethod(index));
        }
        pool.shutdown();
        while (!pool.isTerminated()){
            Thread.sleep(1000);
            System.out.println("還沒停止。。。");
        }
        System.out.println("全部執(zhí)行完畢");
    }


    /**
     * 方法二:getCompletedTaskCount
     * @param args
     * @throws InterruptedException
     */
    public static void completedTaskCountTest(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> sleepMethod(index));
        }
        //當(dāng)線程池完成的線程數(shù)等于線程池中的總線程數(shù)
        while (!(pool.getTaskCount() == pool.getCompletedTaskCount())) {
            System.out.println("任務(wù)總數(shù):" + pool.getTaskCount() + "; 已經(jīng)完成任務(wù)數(shù):" + pool.getCompletedTaskCount());
            Thread.sleep(1000);
            System.out.println("還沒停止。。。");
        }
        System.out.println("全部執(zhí)行完畢");
    }

    /**
     * 方法三:CountDownLatch
     * @throws Exception
     */
    public static void countDownLatchTest(String[] args) throws Exception {
        //計數(shù)器,判斷線程是否執(zhí)行結(jié)束
        CountDownLatch taskLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> {
                sleepMethod(index);
                taskLatch.countDown();
                System.out.println("當(dāng)前計數(shù)器數(shù)量:" + taskLatch.getCount());
            });
        }
        //當(dāng)前線程阻塞,等待計數(shù)器置為0
        taskLatch.await();
        System.out.println("全部執(zhí)行完畢");
    }

    private static int taskNum = 0;

    /**
     * 方法四:公共計數(shù)
     * @throws Exception
     */
    public static void countTest(String[] args) throws Exception {
        Lock lock = new ReentrantLock();
        for (int i = 0; i < 10; i++) {
            int index = i;
            pool.execute(() -> {
                sleepMethod(index);
                lock.lock();
                taskNum++;
                lock.unlock();
            });
        }
        while(taskNum < 10) {
            Thread.sleep(1000);
            System.out.println("還沒停止。。。當(dāng)前完成任務(wù)數(shù):" + taskNum);
        }
        System.out.println("全部執(zhí)行完畢");
    }

    /**
     * 方法五:Future
     * @throws Exception
     */
    public static void futureTest(String[] args) throws Exception {
        Future future = pool.submit(() -> sleepMethod(1));
        while (!future.isDone()){
            Thread.sleep(1000);
            System.out.println("還沒停止。。。");
        }
        System.out.println("全部執(zhí)行完畢");
    }
}


責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2023-08-04 11:04:03

線程池項目開發(fā)

2022-03-30 08:54:21

線程 Thread判斷線程池任務(wù)Java

2022-10-18 10:41:44

Flowable服務(wù)任務(wù)

2024-11-27 13:25:24

Rust線程池線程

2023-12-29 09:38:00

Java線程池

2022-03-28 08:31:29

線程池定時任務(wù)

2020-09-23 16:31:38

C++C++11啟動線程

2020-12-17 05:52:09

線程池ThreadPoolThreadPoolE

2011-11-25 10:25:27

SpringJava

2009-08-28 16:16:02

線程運行狀態(tài)

2024-11-06 09:39:52

2010-01-15 13:30:37

VB.NET并發(fā)性

2010-08-27 09:10:15

網(wǎng)絡(luò)隱私

2009-06-19 18:26:38

Spring事務(wù)配置

2011-02-28 13:51:30

Spring事物配置

2024-01-22 09:51:37

ChatGPT編程任務(wù)程序

2023-11-29 16:38:12

線程池阻塞隊列開發(fā)

2018-09-10 15:58:49

2022-12-27 14:21:42

VR

2010-08-13 13:25:53

Flex頁面跳轉(zhuǎn)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久电影一区 | 日韩av在线免费 | 亚洲一区在线日韩在线深爱 | 成人免费毛片片v | 亚洲网站观看 | 欧美高清视频在线观看 | 久久久久久九九九九九九 | 美女天堂在线 | 久久久久久91香蕉国产 | 精品国产一区二区三区久久 | 日韩av一区二区在线观看 | 久久久国产一区二区三区 | 爱综合| 国产精品影视在线观看 | 国产黄色大片在线观看 | 人人干超碰 | 全免费a级毛片免费看视频免 | 在线观看免费高清av | 91精品国产一区二区三区 | 国产成人免费网站 | 狠狠插天天干 | 国产美女高潮 | 99re在线视频免费观看 | 欧美日韩成人在线 | 羞羞午夜 | 国产精品毛片一区二区三区 | 国产剧情久久 | 午夜视频网| 午夜天堂精品久久久久 | 国产精品亚洲综合 | 国产午夜精品视频 | 在线视频91 | 国产精品久久久久久久久久久久久久 | 欧美一区二区三区在线 | 视频一区二区在线观看 | 国产精品福利在线 | 日本网站在线看 | 大乳boobs巨大吃奶挤奶 | 人人做人人澡人人爽欧美 | 久久久国产视频 | 在线播放国产视频 |