最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解如何在Java8中創(chuàng)建和使用線程池

 更新時(shí)間:2024年06月14日 09:41:42   作者:wljslmz  
在 Java 8 中,線程池(Thread Pool)是一種管理線程資源的機(jī)制,能夠有效地控制并發(fā)執(zhí)行的線程數(shù)量,減少線程創(chuàng)建和銷毀的開銷,提高系統(tǒng)的性能,本篇文章將詳細(xì)介紹如何在 Java 8 中創(chuàng)建和使用線程池,需要的朋友可以參考下

在 Java 8 中,線程池(Thread Pool)是一種管理線程資源的機(jī)制,能夠有效地控制并發(fā)執(zhí)行的線程數(shù)量,減少線程創(chuàng)建和銷毀的開銷,提高系統(tǒng)的性能。Java 提供了 java.util.concurrent 包,其中包含了一些用于創(chuàng)建和管理線程池的類和接口。本篇文章將詳細(xì)介紹如何在 Java 8 中創(chuàng)建和使用線程池。

一、線程池的基本概念

1. 線程池的工作原理

線程池的基本原理是預(yù)先創(chuàng)建若干個(gè)線程,并將它們放入一個(gè)池中。應(yīng)用程序提交的任務(wù)被放入一個(gè)隊(duì)列中,線程池中的線程不斷從隊(duì)列中取出任務(wù)并執(zhí)行。這樣做有以下優(yōu)點(diǎn):

  1. 減少了線程創(chuàng)建和銷毀的開銷:線程的創(chuàng)建和銷毀是昂貴的操作,使用線程池可以重用線程,減少這些開銷。
  2. 提高了響應(yīng)速度:由于線程已經(jīng)存在,可以立即執(zhí)行任務(wù),減少了等待時(shí)間。
  3. 便于管理線程:可以通過配置線程池的大小,控制系統(tǒng)并發(fā)線程的數(shù)量,避免過多線程導(dǎo)致的資源耗盡問題。

2. 線程池的類型

Java 提供了幾種常用的線程池:

  • FixedThreadPool:固定大小的線程池,線程數(shù)量不會改變。
  • CachedThreadPool:根據(jù)需要創(chuàng)建新線程的線程池,但在一定時(shí)間內(nèi)未被使用的線程將被終止并移出緩存。
  • SingleThreadExecutor:單線程的線程池,所有任務(wù)將順序執(zhí)行。
  • ScheduledThreadPool:可以延遲或定期執(zhí)行任務(wù)的線程池。

二、創(chuàng)建線程池

Java 8 中提供了 Executors 工具類來創(chuàng)建各種類型的線程池。

1. 創(chuàng)建固定大小的線程池

使用 Executors.newFixedThreadPool(int nThreads) 方法可以創(chuàng)建一個(gè)固定大小的線程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        
        for (int i = 0; i < 10; i++) {
            Runnable task = new Task(i);
            executorService.execute(task);
        }
        
        executorService.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
    }
}

在上述代碼中,Executors.newFixedThreadPool(5) 創(chuàng)建了一個(gè)包含 5 個(gè)線程的線程池。通過 executorService.execute(task) 提交任務(wù)給線程池執(zhí)行。

2. 創(chuàng)建緩存線程池

使用 Executors.newCachedThreadPool() 方法可以創(chuàng)建一個(gè)緩存線程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        
        for (int i = 0; i < 10; i++) {
            Runnable task = new Task(i);
            executorService.execute(task);
        }
        
        executorService.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
    }
}

Executors.newCachedThreadPool() 創(chuàng)建了一個(gè)緩存線程池,能夠根據(jù)需要創(chuàng)建新線程。如果有空閑線程則重用它們,否則創(chuàng)建新的線程。

3. 創(chuàng)建單線程線程池

使用 Executors.newSingleThreadExecutor() 方法可以創(chuàng)建一個(gè)單線程線程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadExecutorExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        
        for (int i = 0; i < 10; i++) {
            Runnable task = new Task(i);
            executorService.execute(task);
        }
        
        executorService.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
    }
}

在上述代碼中,Executors.newSingleThreadExecutor() 創(chuàng)建了一個(gè)單線程線程池,所有任務(wù)將順序執(zhí)行。

4. 創(chuàng)建調(diào)度線程池

使用 Executors.newScheduledThreadPool(int corePoolSize) 方法可以創(chuàng)建一個(gè)調(diào)度線程池。

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
        
        Runnable task = new Task(1);
        scheduledExecutorService.schedule(task, 5, TimeUnit.SECONDS);
        
        scheduledExecutorService.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
    }
}

在上述代碼中,Executors.newScheduledThreadPool(5) 創(chuàng)建了一個(gè)包含 5 個(gè)線程的調(diào)度線程池。scheduledExecutorService.schedule(task, 5, TimeUnit.SECONDS) 調(diào)度任務(wù)在 5 秒后執(zhí)行。

三、線程池的配置

1. 自定義線程池

可以使用 ThreadPoolExecutor 類創(chuàng)建自定義線程池。該類提供了更多的配置選項(xiàng),如核心線程數(shù)、最大線程數(shù)、空閑線程存活時(shí)間、任務(wù)隊(duì)列等。

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

public class CustomThreadPoolExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()
        );
        
        for (int i = 0; i < 20; i++) {
            Runnable task = new Task(i);
            executor.execute(task);
        }
        
        executor.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
    }
}

在上述代碼中,ThreadPoolExecutor 的構(gòu)造函數(shù)接受多個(gè)參數(shù):

  • 核心線程數(shù):保持在池中的線程數(shù),即使它們處于空閑狀態(tài)。
  • 最大線程數(shù):池中允許的最大線程數(shù)。
  • 空閑線程存活時(shí)間:當(dāng)線程數(shù)超過核心線程數(shù)時(shí),多余的空閑線程存活的最長時(shí)間。
  • 時(shí)間單位:空閑線程存活時(shí)間的時(shí)間單位。
  • 任務(wù)隊(duì)列:存放待執(zhí)行任務(wù)的隊(duì)列。

2. 配置拒絕策略

當(dāng)線程池?zé)o法接受更多任務(wù)時(shí),可以配置拒絕策略。常見的拒絕策略有:

  • AbortPolicy:直接拋出 RejectedExecutionException 異常。
  • CallerRunsPolicy:由調(diào)用線程處理該任務(wù)。
  • DiscardPolicy:直接丟棄任務(wù),不予處理。
  • DiscardOldestPolicy:丟棄隊(duì)列中最舊的任務(wù),然后嘗試提交新任務(wù)。
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;

public class CustomThreadPoolWithRejectionPolicyExample {
    public static void main(String[] args) {
        RejectedExecutionHandler rejectionHandler = new AbortPolicy();
        
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10), rejectionHandler
        );
        
        for (int i = 0; i < 30; i++) {
            Runnable task = new Task(i);
            executor.execute(task);
        }
        
        executor.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
    }
}

在上述代碼中,使用 AbortPolicy 作為拒絕策略。當(dāng)線程池和隊(duì)列都滿時(shí),再提交

任務(wù)將拋出 RejectedExecutionException 異常。

四、線程池的管理和監(jiān)控

1. 管理線程池

線程池的管理主要包括以下幾個(gè)方面:

  • 關(guān)閉線程池:調(diào)用 shutdown() 或 shutdownNow() 方法關(guān)閉線程池。
    • shutdown():平滑關(guān)閉,等待所有已提交的任務(wù)完成后關(guān)閉。
    • shutdownNow():立即關(guān)閉,嘗試中斷正在執(zhí)行的任務(wù)并返回未執(zhí)行的任務(wù)列表。
executorService.shutdown();
// 或
executorService.shutdownNow();
  • 獲取線程池狀態(tài):可以通過 isShutdown()、isTerminated() 方法獲取線程池的狀態(tài)。
if (executorService.isShutdown()) {
    System.out.println("ThreadPool is shutdown.");
}

if (executorService.isTerminated()) {
    System.out.println("All tasks are terminated.");
}

2. 監(jiān)控線程池

可以通過 ThreadPoolExecutor 提供的方法獲取線程池的運(yùn)行狀態(tài):

  • getPoolSize():返回當(dāng)前線程池中的線程數(shù)。
  • getActiveCount():返回正在執(zhí)行任務(wù)的線程數(shù)。
  • getCompletedTaskCount():返回已完成的任務(wù)數(shù)。
  • getTaskCount():返回已提交的任務(wù)數(shù)。
ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;

System.out.println("Pool Size: " + executor.getPoolSize());
System.out.println("Active Threads: " + executor.getActiveCount());
System.out.println("Completed Tasks: " + executor.getCompletedTaskCount());
System.out.println("Total Tasks: " + executor.getTaskCount());

通過這些方法,可以實(shí)時(shí)監(jiān)控線程池的運(yùn)行情況,及時(shí)發(fā)現(xiàn)問題并進(jìn)行調(diào)整。

五、示例:使用線程池進(jìn)行并發(fā)編程

下面是一個(gè)完整的示例,展示了如何使用固定大小的線程池進(jìn)行并發(fā)編程。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 創(chuàng)建固定大小的線程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        
        // 提交任務(wù)
        for (int i = 0; i < 10; i++) {
            Runnable task = new Task(i);
            executorService.execute(task);
        }
        
        // 監(jiān)控線程池狀態(tài)
        ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
        System.out.println("Pool Size: " + executor.getPoolSize());
        System.out.println("Active Threads: " + executor.getActiveCount());
        System.out.println("Completed Tasks: " + executor.getCompletedTaskCount());
        System.out.println("Total Tasks: " + executor.getTaskCount());
        
        // 關(guān)閉線程池
        executorService.shutdown();
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000); // 模擬任務(wù)執(zhí)行時(shí)間
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("Completed task " + taskId + " by " + Thread.currentThread().getName());
    }
}

在這個(gè)示例中,創(chuàng)建了一個(gè)包含 5 個(gè)線程的固定大小的線程池,并提交了 10 個(gè)任務(wù)。通過監(jiān)控線程池的狀態(tài),可以查看線程池的運(yùn)行情況,并在所有任務(wù)完成后關(guān)閉線程池。

總結(jié)

本文詳細(xì)介紹了如何在 Java 8 中創(chuàng)建和使用線程池。通過使用線程池,可以有效管理并發(fā)執(zhí)行的線程數(shù)量,提高系統(tǒng)性能并降低資源消耗。Java 提供了多種類型的線程池,可以根據(jù)不同的應(yīng)用場景選擇合適的線程池。同時(shí),可以通過自定義線程池和配置拒絕策略來滿足特殊需求,并通過監(jiān)控線程池的運(yùn)行狀態(tài)進(jìn)行優(yōu)化和調(diào)整。

以上就是詳解如何在Java8中創(chuàng)建和使用線程池的詳細(xì)內(nèi)容,更多關(guān)于Java8創(chuàng)建和使用線程池的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM

    用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM

    這篇文章主要介紹了用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM的方法,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下
    2021-04-04
  • 一個(gè)簡單的類加載器URLClassLoader案例

    一個(gè)簡單的類加載器URLClassLoader案例

    這篇文章主要介紹了一個(gè)簡單的類加載器URLClassLoader案例,這里寫了一個(gè)小 demo,來加深對于反射的理解,需要的朋友可以參考下
    2023-04-04
  • Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())

    Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())

    在調(diào)外部接口獲取列表數(shù)據(jù)時(shí),需要判斷是否已經(jīng)取完了所有的值,因此需要用到向上取整,下面這篇文章主要給大家介紹了關(guān)于Java兩整數(shù)相除向上取整的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • JAVA垃圾收集器與內(nèi)存分配策略詳解

    JAVA垃圾收集器與內(nèi)存分配策略詳解

    這篇文章介紹了JAVA垃圾收集器與內(nèi)存分配策略,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-07-07
  • SpringBoot詳細(xì)講解日志文件

    SpringBoot詳細(xì)講解日志文件

    Spring Boot默認(rèn)使用SLF4J+Logback 記錄日志,并提供了默認(rèn)配置,即使我們不進(jìn)行任何額外配,也可以使用SLF4J+Logback進(jìn)行日志輸出
    2022-06-06
  • SpringBoot將Spring fox更換為Springdoc的方法詳解

    SpringBoot將Spring fox更換為Springdoc的方法詳解

    由于項(xiàng)目中使用Spring fox已經(jīng)不維護(hù)更新了,代碼掃描,掃出問題,需要將Spring fox更換為Spring Doc,所以本文給大家介紹了SpringBoot將Spring fox更換為Springdoc的方法,文中有相關(guān)的代碼供大家參考,需要的朋友可以參考下
    2024-01-01
  • java實(shí)現(xiàn)數(shù)據(jù)庫主鍵生成示例

    java實(shí)現(xiàn)數(shù)據(jù)庫主鍵生成示例

    這篇文章主要介紹了java實(shí)現(xiàn)數(shù)據(jù)庫主鍵生成示例,需要的朋友可以參考下
    2014-03-03
  • IntelliJ IDEA 好用插件之a(chǎn)nalyze inspect code詳解

    IntelliJ IDEA 好用插件之a(chǎn)nalyze inspect code詳解

    這篇文章主要介紹了IntelliJ IDEA 好用插件之a(chǎn)nalyze inspect code的相關(guān)知識,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-12-12
  • Java類成員訪問權(quán)限控制知識總結(jié)

    Java類成員訪問權(quán)限控制知識總結(jié)

    這篇文章主要介紹了Java類成員訪問權(quán)限控制知識總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • springboot大文件上傳、分片上傳、斷點(diǎn)續(xù)傳、秒傳的實(shí)現(xiàn)

    springboot大文件上傳、分片上傳、斷點(diǎn)續(xù)傳、秒傳的實(shí)現(xiàn)

    本文主要介紹了springboot大文件上傳、分片上傳、斷點(diǎn)續(xù)傳、秒傳的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評論

贺兰县| 垦利县| 宜宾县| 三台县| 肃南| 赣榆县| 云林县| 耒阳市| 杭锦后旗| 旌德县| 云梦县| 海伦市| 常州市| 永嘉县| 玉环县| 扎鲁特旗| 福泉市| 墨玉县| 清水河县| 高淳县| 荔浦县| 岳池县| 宜君县| 明星| 加查县| 松江区| 同心县| 保康县| 乐山市| 阳山县| 东明县| 德惠市| 长宁县| 毕节市| 深泽县| 乌什县| 偏关县| 宣城市| 噶尔县| 花垣县| 当雄县|