欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java異步判斷線程池所有任務(wù)是否執(zhí)行完成的操作方法

 更新時間:2024年07月12日 09:42:02   作者:TS86  
這篇文章主要介紹了Java異步判斷線程池所有任務(wù)是否執(zhí)行完成的方法,在這個示例中,我使用了傳統(tǒng)的匿名內(nèi)部類來創(chuàng)建Callable任務(wù)(同時也提供了Lambda表達(dá)式的注釋),以便與各種Java版本兼容,需要的朋友可以參考下

1.使用ExecutorService和CountDownLatch的方法示例

在Java中,當(dāng)我們使用線程池(如ExecutorService)來執(zhí)行異步任務(wù)時,常常需要知道所有任務(wù)是否都已經(jīng)完成。ExecutorService接口提供了幾種方式來處理這種情況,但最常用的是shutdown()awaitTermination()方法的組合,或者使用FutureCompletionService。這里我將提供一個使用ExecutorServiceCountDownLatch的示例,因為CountDownLatch提供了一種直觀的方式來等待一組線程完成。

首先,我們定義幾個任務(wù),然后使用ExecutorService來異步執(zhí)行它們,并使用CountDownLatch來等待所有任務(wù)完成。

import java.util.concurrent.*;  
public class ThreadPoolExample {  
    public static void main(String[] args) throws InterruptedException {  
        // 創(chuàng)建一個包含固定數(shù)量線程的線程池  
        ExecutorService executorService = Executors.newFixedThreadPool(4);  
        // 定義任務(wù)數(shù)量  
        int taskCount = 10;  
        // 使用CountDownLatch來等待所有任務(wù)完成  
        final CountDownLatch latch = new CountDownLatch(taskCount);  
        // 提交任務(wù)到線程池  
        for (int i = 0; i < taskCount; i++) {  
            int taskId = i;  
            executorService.submit(() -> {  
                // 模擬任務(wù)執(zhí)行  
                try {  
                    Thread.sleep(1000); // 假設(shè)每個任務(wù)需要1秒  
                } catch (InterruptedException e) {  
                    Thread.currentThread().interrupt();  
                }  
                System.out.println("任務(wù) " + taskId + " 完成");  
                // 每完成一個任務(wù),計數(shù)減一  
                latch.countDown();  
            });  
        }  
        // 等待所有任務(wù)完成  
        System.out.println("等待所有任務(wù)完成...");  
        latch.await(); // 阻塞當(dāng)前線程,直到latch的計數(shù)達(dá)到零  
        System.out.println("所有任務(wù)完成!");  
        // 關(guān)閉線程池  
        executorService.shutdown();  
        // 可選:等待線程池中的線程都執(zhí)行完畢  
        try {  
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {  
                // 線程池沒有在規(guī)定時間內(nèi)關(guān)閉,則強制關(guān)閉  
                executorService.shutdownNow();  
            }  
        } catch (InterruptedException e) {  
            // 當(dāng)前線程在等待過程中被中斷  
            executorService.shutdownNow();  
            Thread.currentThread().interrupt();  
        }  
    }  
}

在這個例子中,我們首先創(chuàng)建了一個固定大小的線程池(這里使用4個線程)。然后,我們定義了一個CountDownLatch,其計數(shù)被初始化為任務(wù)的數(shù)量(這里為10)。對于每個任務(wù),我們都向線程池提交了一個Runnable,其中包含了任務(wù)的執(zhí)行邏輯和latch.countDown()調(diào)用,以確保每次任務(wù)完成時都會減少CountDownLatch的計數(shù)。

主線程通過調(diào)用latch.await()來等待,直到所有任務(wù)都調(diào)用了countDown()(即計數(shù)達(dá)到零),然后才能繼續(xù)執(zhí)行。這確保了主線程會等待所有任務(wù)完成后再繼續(xù)。

最后,我們關(guān)閉了線程池,并通過調(diào)用awaitTermination()來可選地等待線程池中的所有線程都執(zhí)行完畢。如果線程池沒有在指定時間內(nèi)關(guān)閉,則調(diào)用shutdownNow()來嘗試立即停止所有正在執(zhí)行的任務(wù)。

這個示例提供了處理異步任務(wù)并等待它們完成的一種有效方式,適用于需要等待所有任務(wù)完成再繼續(xù)的場景。

2.使用ExecutorService的invokeAll方法和Future列表的方法示例

除了使用CountDownLatch之外,還有其他方法可以判斷線程池中的所有任務(wù)是否執(zhí)行完成。以下是一個使用ExecutorServiceinvokeAll方法和Future列表的示例,這種方法適用于我們有一組已知的任務(wù)(Callable)需要并行執(zhí)行,并且我們需要等待所有任務(wù)完成并獲取它們的結(jié)果。

import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.*;  
public class ThreadPoolFutureExample {  
    public static void main(String[] args) throws InterruptedException, ExecutionException {  
        // 創(chuàng)建一個包含固定數(shù)量線程的線程池  
        ExecutorService executorService = Executors.newFixedThreadPool(4);  
        // 創(chuàng)建一個Callable任務(wù)列表  
        List<Callable<String>> tasks = new ArrayList<>();  
        for (int i = 0; i < 10; i++) {  
            final int taskId = i;  
            tasks.add(() -> {  
                // 模擬任務(wù)執(zhí)行  
                Thread.sleep(1000); // 假設(shè)每個任務(wù)需要1秒  
                return "任務(wù) " + taskId + " 完成";  
            });  
        }  
        // 使用invokeAll提交所有任務(wù),這將返回一個Future列表  
        List<Future<String>> futures = executorService.invokeAll(tasks);  
        // 遍歷Future列表,獲取每個任務(wù)的結(jié)果  
        for (Future<String> future : futures) {  
            // get()會阻塞,直到對應(yīng)的任務(wù)完成  
            System.out.println(future.get());  
        }  
        // 關(guān)閉線程池  
        executorService.shutdown();  
        // 可選:等待線程池中的線程都執(zhí)行完畢  
        try {  
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {  
                // 線程池沒有在規(guī)定時間內(nèi)關(guān)閉,則強制關(guān)閉  
                executorService.shutdownNow();  
            }  
        } catch (InterruptedException e) {  
            // 當(dāng)前線程在等待過程中被中斷  
            executorService.shutdownNow();  
            Thread.currentThread().interrupt();  
        }  
    }  
}  
// 注意:這里使用了Lambda表達(dá)式和方法引用來簡化Callable的創(chuàng)建  
// 實際使用中,你可能需要實現(xiàn)Callable接口或使用匿名內(nèi)部類

在這個例子中,我們創(chuàng)建了一個ExecutorService和一個Callable任務(wù)列表。每個Callable任務(wù)都會返回一個字符串,表示任務(wù)完成的信息。我們使用invokeAll方法提交了所有任務(wù),并立即獲得了一個Future列表,每個Future都代表了一個任務(wù)的執(zhí)行結(jié)果。

然后,我們遍歷這個Future列表,并對每個Future調(diào)用get()方法。get()方法會阻塞當(dāng)前線程,直到對應(yīng)的任務(wù)完成并返回結(jié)果。這樣,我們就能確保在繼續(xù)執(zhí)行之前,所有任務(wù)都已經(jīng)完成。

最后,我們關(guān)閉了線程池,并等待所有線程都執(zhí)行完畢(或超時后強制關(guān)閉)。

請注意,雖然這個示例使用了CallableFuture,但它并沒有直接提供一個“是否所有任務(wù)都已完成”的布爾值。然而,通過遍歷Future列表并調(diào)用get(),我們實際上已經(jīng)達(dá)到了等待所有任務(wù)完成的效果。如果我們只需要知道是否所有任務(wù)都已開始執(zhí)行(而不是等待它們完成),那么我們可能需要采用不同的策略,比如使用execute方法結(jié)合其他同步機制(如CountDownLatch)。

3.使用ExecutorService來異步執(zhí)行多個Callable任務(wù)方法示例

以下是一個詳細(xì)完整的代碼示例,該示例使用了ExecutorService來異步執(zhí)行多個Callable任務(wù),并通過遍歷Future列表來等待所有任務(wù)完成并獲取它們的結(jié)果。

import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.*;  
public class ThreadPoolFutureCompleteExample {  
    public static void main(String[] args) {  
        // 創(chuàng)建一個包含固定數(shù)量線程的線程池  
        ExecutorService executorService = Executors.newFixedThreadPool(4);  
        // 創(chuàng)建一個Callable任務(wù)列表  
        List<Callable<String>> tasks = new ArrayList<>();  
        for (int i = 0; i < 10; i++) {  
            final int taskId = i;  
            tasks.add(new Callable<String>() {  
                @Override  
                public String call() throws Exception {  
                    // 模擬任務(wù)執(zhí)行  
                    TimeUnit.SECONDS.sleep(1); // 假設(shè)每個任務(wù)需要1秒  
                    return "任務(wù) " + taskId + " 完成";  
                }  
            });  
            // 或者使用Lambda表達(dá)式(如果你使用的是Java 8或更高版本)  
            // tasks.add(() -> {  
            //     TimeUnit.SECONDS.sleep(1);  
            //     return "任務(wù) " + taskId + " 完成";  
            // });  
        }  
        try {  
            // 使用invokeAll提交所有任務(wù),這將返回一個Future列表  
            List<Future<String>> futures = executorService.invokeAll(tasks);  
            // 遍歷Future列表,獲取每個任務(wù)的結(jié)果  
            for (Future<String> future : futures) {  
                // get()會阻塞,直到對應(yīng)的任務(wù)完成  
                System.out.println(future.get());  
            }  
            // 關(guān)閉線程池  
            executorService.shutdown();  
            // 等待線程池中的所有線程都執(zhí)行完畢(可選)  
            // 注意:由于我們已經(jīng)調(diào)用了invokeAll并等待了所有Future的完成,這一步通常是多余的  
            // 但為了完整性,我還是展示了如何等待線程池關(guān)閉  
            boolean terminated = executorService.awaitTermination(60, TimeUnit.SECONDS);  
            if (!terminated) {  
                // 如果線程池沒有在規(guī)定時間內(nèi)關(guān)閉,則強制關(guān)閉  
                System.err.println("線程池沒有在規(guī)定時間內(nèi)關(guān)閉,嘗試強制關(guān)閉...");  
                executorService.shutdownNow();  
                // 注意:shutdownNow()不保證已經(jīng)提交的任務(wù)會被取消  
                // 它會嘗試停止正在執(zhí)行的任務(wù),但已經(jīng)開始執(zhí)行的任務(wù)可能無法被中斷  
            }  
        } catch (InterruptedException | ExecutionException e) {  
            // 處理異常  
            e.printStackTrace();  
            // 如果當(dāng)前線程在等待過程中被中斷,嘗試關(guān)閉線程池  
            if (!executorService.isShutdown()) {  
                executorService.shutdownNow();  
            }  
            // 根據(jù)需要,可能還需要重新設(shè)置中斷狀態(tài)  
            Thread.currentThread().interrupt();  
        }  
    }  
}

在這個示例中,我使用了傳統(tǒng)的匿名內(nèi)部類來創(chuàng)建Callable任務(wù)(同時也提供了Lambda表達(dá)式的注釋),以便與各種Java版本兼容。然而,如果我們正在使用Java 8或更高版本,我強烈推薦我們使用Lambda表達(dá)式來簡化代碼。

請注意,invokeAll方法會阻塞調(diào)用它的線程,直到所有任務(wù)都完成,或者直到等待超時(如果我們提供了超時時間)。但是,在這個示例中,我們沒有為invokeAll提供超時時間,因此它會一直等待,直到所有任務(wù)都完成。

另外,請注意,在catch塊中,如果捕獲到InterruptedException,我們檢查了線程池是否已經(jīng)被關(guān)閉(使用isShutdown方法)。如果沒有,我們調(diào)用shutdownNow方法來嘗試關(guān)閉線程池并停止正在執(zhí)行的任務(wù)。然而,需要注意的是,shutdownNow方法并不保證能夠停止所有已經(jīng)開始執(zhí)行的任務(wù),因為某些任務(wù)可能無法被中斷。

最后,如果在捕獲到InterruptedException后,我們確定當(dāng)前線程需要被重新中斷(比如,我們在一個循環(huán)中等待某個條件,而中斷是用來退出循環(huán)的),那么我們應(yīng)該調(diào)用Thread.currentThread().interrupt()來重新設(shè)置中斷狀態(tài)。在這個示例中,我們沒有這樣做,因為main方法不需要重新中斷。但是,在更復(fù)雜的場景中,這可能是必要的。

到此這篇關(guān)于Java異步判斷線程池所有任務(wù)是否執(zhí)行完成的方法的文章就介紹到這了,更多相關(guān)Java異步判斷線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java設(shè)計模式之代理模式詳細(xì)解讀

    Java設(shè)計模式之代理模式詳細(xì)解讀

    這篇文章主要介紹了Java設(shè)計模式的代理模式,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)Java設(shè)計模式的小伙伴有很大的幫助,感興趣的小伙伴可以參考一下
    2021-08-08
  • Java幾個實例帶你進(jìn)階升華上篇

    Java幾個實例帶你進(jìn)階升華上篇

    與其明天開始,不如現(xiàn)在行動,本文為你帶來幾個Java書寫的實際案例,對鞏固編程的基礎(chǔ)能力很有幫助,快來一起往下看看吧
    2022-03-03
  • Springboot?接口需要接收參數(shù)類型是數(shù)組問題

    Springboot?接口需要接收參數(shù)類型是數(shù)組問題

    這篇文章主要介紹了Springboot?接口需要接收參數(shù)類型是數(shù)組問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Struts2 OGNL表達(dá)式實例詳解

    Struts2 OGNL表達(dá)式實例詳解

    這篇文章主要介紹了Struts2 OGNL表達(dá)式實例詳解,相關(guān)實例代碼,需要的朋友可以參考。
    2017-09-09
  • 解析Java中未被捕獲的異常以及try語句的嵌套使用

    解析Java中未被捕獲的異常以及try語句的嵌套使用

    這篇文章主要介紹了Java中未被捕獲的異常以及try語句的嵌套使用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • Java手把手必會的實例漢諾塔講解練習(xí)

    Java手把手必會的實例漢諾塔講解練習(xí)

    漢諾塔,傳說神在創(chuàng)造世界的時候做了三根金剛石柱子,并在一個教塔里留下了三根金剛石棒,第一根上面從上到下套著64個按從小到大排列的金盤,神命令廟里的眾僧將它們一個個地從這根金剛石棒搬到另一根金剛石棒上,大盤不能放在小盤上。最后64個金盤仍然要按從小到大排列
    2021-09-09
  • Java的“Goto”與標(biāo)簽及使用詳解

    Java的“Goto”與標(biāo)簽及使用詳解

    goto在Java中是一個保留字,但在語言中并沒有用到它;Java沒有g(shù)oto。接下來通過本文給大家介紹Java的“Goto”與標(biāo)簽,感興趣的朋友跟隨小編一起看看吧
    2018-10-10
  • Java日期時間與正則表達(dá)式超詳細(xì)整理(適合新手入門)

    Java日期時間與正則表達(dá)式超詳細(xì)整理(適合新手入門)

    如果使用得當(dāng),正則表達(dá)式是匹配各種模式的強大工具,下面這篇文章主要給大家介紹了關(guān)于Java日期時間與正則表達(dá)式超詳細(xì)整理的相關(guān)資料,本文非常適合新手入門,需要的朋友可以參考下
    2023-04-04
  • servlet轉(zhuǎn)發(fā)、包含詳解(七)

    servlet轉(zhuǎn)發(fā)、包含詳解(七)

    這篇文章主要為大家詳細(xì)介紹了servlet轉(zhuǎn)發(fā)、包含的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • spring boot利用docker構(gòu)建gradle項目的實現(xiàn)步驟

    spring boot利用docker構(gòu)建gradle項目的實現(xiàn)步驟

    這篇文章主要給大家介紹了關(guān)于spring boot利用docker構(gòu)建gradle項目的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05

最新評論