偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

線程池,你會用嗎?(沒有做到精通的請進)

開發(fā) 前端
線程池是Java并發(fā)編程中的重要工具,無論是Java原生的Executor框架還是Guava庫提供的擴展,都為我們提供了強大的異步任務(wù)處理能力。


在Java并發(fā)編程領(lǐng)域,線程池是一種至關(guān)重要的工具,它能顯著提升應(yīng)用程序的性能與資源管理效率。通過復(fù)用線程,線程池避免了頻繁創(chuàng)建和銷毀線程所帶來的開銷。在本教程中,我們將深入探討Java和Guava庫中線程池的使用。

一、Java中的線程池

(一)Executor框架

Java的java.util.concurrent包提供了Executor框架,這是管理線程池的核心。

Executor接口是該框架的基礎(chǔ),它定義了一個簡單的方法execute(Runnable task),用于提交任務(wù)執(zhí)行。

Executor接口本身并不直接管理線程,而是將任務(wù)的執(zhí)行委托給實現(xiàn)類。

(二)ExecutorService

ExecutorService接口擴展了Executor接口,提供了更豐富的功能,用于管理線程池的生命周期以及任務(wù)的提交與執(zhí)行。它包含了啟動、關(guān)閉線程池的方法,以及提交任務(wù)并獲取執(zhí)行結(jié)果的方法。

2.1 創(chuàng)建線程池

在Java中,我們可以使用Executors類的靜態(tài)方法來創(chuàng)建不同類型的線程池:

  • FixedThreadPool:創(chuàng)建一個固定大小的線程池,線程池中的線程數(shù)量在創(chuàng)建時就被確定,并且不會改變。如果提交的任務(wù)數(shù)量超過了線程池的容量,任務(wù)將被放入隊列中等待執(zhí)行。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
  • CachedThreadPool:創(chuàng)建一個可緩存的線程池,如果線程池中的線程在一段時間內(nèi)沒有被使用,它們將被回收。如果提交的任務(wù)數(shù)量超過了當前線程池中的線程數(shù)量,新的線程將被創(chuàng)建。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  • SingleThreadExecutor:創(chuàng)建一個單線程的線程池,它只使用一個線程來執(zhí)行任務(wù)。所有提交的任務(wù)將按照順序依次執(zhí)行。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
  • ScheduledThreadPool:創(chuàng)建一個支持定時及周期性任務(wù)執(zhí)行的線程池。可以安排任務(wù)在指定的延遲后執(zhí)行,或者定期重復(fù)執(zhí)行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

2.2 提交任務(wù)

一旦創(chuàng)建了線程池,我們可以使用submit方法提交任務(wù)。submit方法有多種重載形式,可接受Runnable或Callable任務(wù),并返回Future對象,通過Future對象可以獲取任務(wù)的執(zhí)行結(jié)果。

Future<Integer> future = fixedThreadPool.submit(() -> {
    // 執(zhí)行任務(wù)并返回結(jié)果
    return 42;
});
try {
    Integer result = future.get();
    System.out.println("任務(wù)執(zhí)行結(jié)果: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

2.3 關(guān)閉線程池

在應(yīng)用程序結(jié)束時,我們需要正確關(guān)閉線程池,以確保所有任務(wù)都能正常完成,并釋放資源。ExecutorService提供了shutdown和shutdownNow方法來實現(xiàn)這一點。

  • shutdown:啟動一個有序關(guān)閉過程,不再接受新任務(wù),但會繼續(xù)執(zhí)行已提交的任務(wù)。
fixedThreadPool.shutdown();
  • shutdownNow:嘗試停止所有正在執(zhí)行的任務(wù),停止等待任務(wù)的處理,并返回等待執(zhí)行的任務(wù)列表。
List<Runnable> tasks = fixedThreadPool.shutdownNow();

(三)示例:使用線程池進行并行計算

假設(shè)我們有一個簡單的任務(wù),需要計算一組數(shù)字的平方。我們可以使用線程池來并行執(zhí)行這些計算,以提高效率。

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        List<Future<Integer>> futures = new ArrayList<>();

        List<Integer> numbers = List.of(1, 2, 3, 4, 5);
        for (int number : numbers) {
            Future<Integer> future = executorService.submit(() -> number * number);
            futures.add(future);
        }

        executorService.shutdown();

        for (Future<Integer> future : futures) {
            try {
                System.out.println("平方結(jié)果: " + future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

運行結(jié)果是:

平方結(jié)果: 1
平方結(jié)果: 4
平方結(jié)果: 9
平方結(jié)果: 16
平方結(jié)果: 25

二、Guava中的線程池

Guava庫提供了ListeningExecutorService接口,它擴展了ExecutorService,并提供了更方便的異步任務(wù)處理方式。ListeningExecutorService允許我們注冊監(jiān)聽器,以便在任務(wù)完成時得到通知。

(一)創(chuàng)建ListeningExecutorService

在Guava中,我們可以使用MoreExecutors類的靜態(tài)方法來創(chuàng)建ListeningExecutorService。例如,我們可以將一個普通的ExecutorService包裝成ListeningExecutorService:

ExecutorService executorService = Executors.newFixedThreadPool(5);
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);

(二)提交任務(wù)并注冊監(jiān)聽器

提交任務(wù)后,我們可以使用Futures.addCallback方法注冊一個回調(diào),當任務(wù)完成時,回調(diào)的onSuccess或onFailure方法將被調(diào)用。

Future<Integer> future = listeningExecutorService.submit(() -> {
    // 執(zhí)行任務(wù)并返回結(jié)果
    return 42;
});

Futures.addCallback(future, new FutureCallback<Integer>() {
    @Override
    public void onSuccess(Integer result) {
        System.out.println("任務(wù)成功執(zhí)行,結(jié)果: " + result);
    }

    @Override
    public void onFailure(Throwable t) {
        System.out.println("任務(wù)執(zhí)行失敗: " + t.getMessage());
    }
});

(三)示例:使用Guava線程池進行異步任務(wù)處理

以下是一個完整的示例,展示如何使用Guava的線程池進行異步任務(wù)處理,并注冊監(jiān)聽器來處理任務(wù)結(jié)果。

public class GuavaThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);

        ListenableFuture<Integer> future = listeningExecutorService.submit(() -> {
            // 模擬任務(wù)執(zhí)行
            Thread.sleep(2000);
            return 42;
        });

        final ExecutorService callbackExecutor = Executors.newFixedThreadPool(3);
        Futures.addCallback(future, new FutureCallback<Integer>() {
            @Override
            public void onSuccess(Integer result) {
                System.out.println("任務(wù)成功執(zhí)行,結(jié)果: " + result);
                callbackExecutor.shutdown();
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("任務(wù)執(zhí)行失敗: " + t.getMessage());
                callbackExecutor.shutdown();
            }
        }, callbackExecutor);

        // 關(guān)閉線程池
        executorService.shutdown();
    }
}

運行結(jié)果是:

任務(wù)成功執(zhí)行,結(jié)果: 42

三、補充

補充一下Executors的工廠方法:

方法

描述

適用場景

newCachedThreadPool

創(chuàng)建一個可緩存的線程池。如果線程池的當前線程數(shù)超過了處理需求,則會回收空閑線程;如果需求增加,則可以添加新線程。

執(zhí)行大量短期異步任務(wù)

newFixedThreadPool

創(chuàng)建一個固定大小的線程池。線程池中的線程數(shù)量固定,如果所有線程都在忙,新的任務(wù)會在隊列中等待。

負載較重且任務(wù)量穩(wěn)定的場景

newScheduledThreadPool

創(chuàng)建一個支持定時及周期性任務(wù)執(zhí)行的線程池??梢哉{(diào)度命令在給定的延遲后運行,或定期執(zhí)行。

需要定時執(zhí)行任務(wù)的場景

newSingleThreadExecutor

創(chuàng)建一個單線程化的線程池。確保所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。

需要保證任務(wù)順序執(zhí)行的場景

newSingleThreadScheduledExecutor

創(chuàng)建一個單線程的定時任務(wù)執(zhí)行器。支持定時及周期性任務(wù)執(zhí)行。

需要單線程執(zhí)行定時任務(wù)的場景

newThreadPerTaskExecutor

創(chuàng)建一個為每個任務(wù)創(chuàng)建新線程的執(zhí)行器。每個任務(wù)都會啟動一個新的線程來執(zhí)行。

任務(wù)之間完全獨立且不需要復(fù)用線程的場景

newVirtualThreadPerTaskExecutor

創(chuàng)建一個為每個任務(wù)創(chuàng)建虛擬線程的執(zhí)行器。虛擬線程是輕量級線程,適用于高并發(fā)場景。

需要高并發(fā)且任務(wù)量大的場景

newWorkStealingPool

創(chuàng)建一個工作竊取線程池。使用 ForkJoinPool 實現(xiàn),線程池中的線程會主動“竊取”其他線程的任務(wù)來執(zhí)行,提高 CPU 利用率。

計算密集型任務(wù),可以充分利用多核處理器的優(yōu)勢

文末總結(jié)

線程池是Java并發(fā)編程中的重要工具,無論是Java原生的Executor框架還是Guava庫提供的擴展,都為我們提供了強大的異步任務(wù)處理能力。通過合理使用線程池,我們可以有效提高應(yīng)用程序的性能和資源利用率。在實際應(yīng)用中,根據(jù)具體需求選擇合適的線程池類型和使用方式至關(guān)重要。

責任編輯:武曉燕 來源: 看山的小屋
相關(guān)推薦

2021-11-03 17:40:51

Python線程

2025-01-20 00:00:00

反射Java語言

2021-09-16 11:02:49

Python線程

2023-06-08 07:48:03

Java線程池

2022-06-24 06:43:57

線程池線程復(fù)用

2020-06-04 14:15:55

Java中BigDecimal函數(shù)

2018-09-29 15:34:34

JavaList接口

2024-03-06 08:15:03

@Autowired注入方式Spring

2021-05-21 12:36:16

限流代碼Java

2021-08-11 10:00:51

緩存MyBatis管理

2021-09-06 10:42:18

Linux命令服務(wù)器

2021-06-01 10:49:22

線程池Java開發(fā)

2021-06-03 14:23:57

線程線程池JAVA

2021-09-02 09:53:42

開發(fā)Redis配置

2019-01-28 17:42:33

Python數(shù)據(jù)預(yù)處理數(shù)據(jù)標準化

2019-07-25 12:46:32

Java高并發(fā)編程語言

2020-11-09 09:03:35

高并發(fā)多線程ThreadLocal

2023-12-28 07:49:11

線程池源碼應(yīng)用場景

2023-01-07 17:41:36

線程池并發(fā)

2019-10-31 08:36:59

線程內(nèi)存操作系統(tǒng)
點贊
收藏

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