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

詳解如何在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ù)量不會(huì)改變。
  • CachedThreadPool:根據(jù)需要?jiǎng)?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ù)需要?jiǎng)?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)文章

  • Java8在遍歷集合時(shí)刪除元素問題解決

    Java8在遍歷集合時(shí)刪除元素問題解決

    本文主要介紹了Java8在遍歷集合時(shí)刪除元素問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • java讀取枚舉類的值轉(zhuǎn)成list和map方式

    java讀取枚舉類的值轉(zhuǎn)成list和map方式

    這篇文章主要介紹了java讀取枚舉類的值轉(zhuǎn)成list和map方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java判斷兩個(gè)List<String>集合是否存在交集三種方法

    java判斷兩個(gè)List<String>集合是否存在交集三種方法

    這篇文章主要介紹了三種判斷Java中兩個(gè)List集合是否存在交集的方法,分別是使用retainAll方法、使用Stream和anyMatch以及使用Set提高性能,每種方法都有其適用場景和優(yōu)缺點(diǎn),需要的朋友可以參考下
    2025-03-03
  • java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明

    java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明

    這篇文章主要介紹了java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java 進(jìn)程執(zhí)行外部程序造成阻塞的一種原因

    Java 進(jìn)程執(zhí)行外部程序造成阻塞的一種原因

    前一陣子在研究文檔展示時(shí)使用了java進(jìn)程直接調(diào)用外部程序,其中遇到一個(gè)問題花了好長時(shí)間才解決,這個(gè)問題就是外部程序直接執(zhí)行沒什么問題,但是當(dāng)使用Java進(jìn)程執(zhí)行時(shí)外部程序就阻塞在那兒不動(dòng)了。而且這個(gè)外部程序在處理某些文件時(shí)使用Java進(jìn)程執(zhí)行是沒問題的
    2014-03-03
  • MapReduce實(shí)現(xiàn)TopN效果示例解析

    MapReduce實(shí)現(xiàn)TopN效果示例解析

    這篇文章主要為大家介紹了MapReduce實(shí)現(xiàn)TopN效果示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Spring AOP實(shí)現(xiàn)Redis緩存數(shù)據(jù)庫查詢源碼

    Spring AOP實(shí)現(xiàn)Redis緩存數(shù)據(jù)庫查詢源碼

    這篇文章主要介紹了Spring AOP實(shí)現(xiàn)Redis緩存數(shù)據(jù)庫查詢的相關(guān)內(nèi)容,源碼部分還是不錯(cuò)的,需要的朋友可以參考下。
    2017-09-09
  • Java 創(chuàng)建并應(yīng)用PPT幻燈片母版的方法示例

    Java 創(chuàng)建并應(yīng)用PPT幻燈片母版的方法示例

    幻燈片母版可供用戶設(shè)置幻燈片的樣式,本文將介紹如何用Java創(chuàng)建并應(yīng)用單個(gè)或多個(gè)幻燈片母版。感興趣可以了解一下
    2020-06-06
  • 簡單了解Spring Framework5.0新特性

    簡單了解Spring Framework5.0新特性

    這篇文章主要介紹了簡單了解Spring Framework5.0新特性,涉及了核心框架修訂,核心容器更新,使用Kotlin進(jìn)行函數(shù)式編程等幾個(gè)方面的介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Springboot文件上傳功能簡單測試

    Springboot文件上傳功能簡單測試

    這篇文章主要介紹了Springboot文件上傳功能簡單測試,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05

最新評(píng)論