91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java線程池代碼怎么寫

發布時間:2023-05-06 10:38:24 來源:億速云 閱讀:89 作者:zzz 欄目:開發技術

這篇“Java線程池代碼怎么寫”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java線程池代碼怎么寫”文章吧。

Java線程池核心原理

看過Java線程池源碼的小伙伴都知道,在Java線程池中最核心的類就是ThreadPoolExecutor,而在ThreadPoolExecutor類中最核心的構造方法就是帶有7個參數的構造方法,如下所示。

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

各參數的含義如下所示。

  • corePoolSize:線程池中的常駐核心線程數。

  • maximumPoolSize:線程池能夠容納同時執行的最大線程數,此值大于等于1。

  • keepAliveTime:多余的空閑線程存活時間,當空間時間達到keepAliveTime值時,多余的線程會被銷毀直到只剩下corePoolSize個線程為止。

  • unit:keepAliveTime的單位。

  • workQueue:任務隊列,被提交但尚未被執行的任務。

  • threadFactory:表示生成線程池中工作線程的線程工廠,用戶創建新線程,一般用默認即可。

  • handler:拒絕策略,表示當線程隊列滿了并且工作線程大于等于線程池的最大顯示數(maxnumPoolSize)時,如何來拒絕請求執行的runnable的策略。

并且Java的線程池是通過 生產者-消費者模式 實現的,線程池的使用方是生產者,而線程池本身就是消費者。

Java線程池的核心工作流程如下圖所示。

Java線程池代碼怎么寫

手擼Java線程池

我們自己手動實現的線程池要比Java自身的線程池簡單的多,我們去掉了各種復雜的處理方式,只保留了最核心的原理:線程池的使用者向任務隊列中添加任務,而線程池本身從任務隊列中消費任務并執行任務。

Java線程池代碼怎么寫

只要理解了這個核心原理,接下來的代碼就簡單多了。在實現這個簡單的線程池時,我們可以將整個實現過程進行拆解。拆解后的實現流程為:定義核心字段、創建內部類WorkThread、創建ThreadPool類的構造方法和創建執行任務的方法。

定義核心字段

首先,我們創建一個名稱為ThreadPool的Java類,并在這個類中定義如下核心字段。

  • DEFAULT_WORKQUEUE_SIZE:靜態常量,表示默認的阻塞隊列大小。

  • workQueue:模擬實際的線程池使用阻塞隊列來實現生產者-消費者模式。

  • workThreads:模擬實際的線程池使用List集合保存線程池內部的工作線程。

核心代碼如下所示。

//默認阻塞隊列大小
private static final int DEFAULT_WORKQUEUE_SIZE = 5;

//模擬實際的線程池使用阻塞隊列來實現生產者-消費者模式
private BlockingQueue<Runnable> workQueue;

//模擬實際的線程池使用List集合保存線程池內部的工作線程
private List<WorkThread> workThreads = new ArrayList<WorkThread>();

創建內部類WordThread

在ThreadPool類中創建一個內部類WorkThread,模擬線程池中的工作線程。主要的作用就是消費workQueue中的任務,并執行任務。由于工作線程需要不斷從workQueue中獲取任務,所以,這里使用了while(true)循環不斷嘗試消費隊列中的任務。

核心代碼如下所示。

//內部類WorkThread,模擬線程池中的工作線程
//主要的作用就是消費workQueue中的任務,并執行
//由于工作線程需要不斷從workQueue中獲取任務,使用了while(true)循環不斷嘗試消費隊列中的任務
class WorkThread extends Thread{
    @Override
    public void run() {
        //不斷循環獲取隊列中的任務
        while (true){
            //當沒有任務時,會阻塞
            try {
                Runnable workTask = workQueue.take();
                workTask.run();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

創建ThreadPool類的構造方法

這里,我們為ThreadPool類創建兩個構造方法,一個構造方法中傳入線程池的容量大小和阻塞隊列,另一個構造方法中只傳入線程池的容量大小。

核心代碼如下所示。

//在ThreadPool的構造方法中傳入線程池的大小和阻塞隊列
public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
    this.workQueue = workQueue;
    //創建poolSize個工作線程并將其加入到workThreads集合中
    IntStream.range(0, poolSize).forEach((i) -> {
        WorkThread workThread = new WorkThread();
        workThread.start();
        workThreads.add(workThread);
    });
}

//在ThreadPool的構造方法中傳入線程池的大小
public ThreadPool(int poolSize){
    this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

創建執行任務的方法

在ThreadPool類中創建執行任務的方法execute(),execute()方法的實現比較簡單,就是將方法接收到的Runnable任務加入到workQueue隊列中。

核心代碼如下所示。

//通過線程池執行任務
public void execute(Runnable task){
    try {
        workQueue.put(task);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

完整源碼

這里,我們給出手動實現的ThreadPool線程池的完整源代碼,如下所示。

package io.binghe.thread.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 自定義線程池
 */
public class ThreadPool {

    //默認阻塞隊列大小
    private static final int DEFAULT_WORKQUEUE_SIZE = 5;

    //模擬實際的線程池使用阻塞隊列來實現生產者-消費者模式
    private BlockingQueue<Runnable> workQueue;

    //模擬實際的線程池使用List集合保存線程池內部的工作線程
    private List<WorkThread> workThreads = new ArrayList<WorkThread>();

    //在ThreadPool的構造方法中傳入線程池的大小和阻塞隊列
    public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
        this.workQueue = workQueue;
        //創建poolSize個工作線程并將其加入到workThreads集合中
        IntStream.range(0, poolSize).forEach((i) -> {
            WorkThread workThread = new WorkThread();
            workThread.start();
            workThreads.add(workThread);
        });
    }

    //在ThreadPool的構造方法中傳入線程池的大小
    public ThreadPool(int poolSize){
        this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
    }

 //通過線程池執行任務
    public void execute(Runnable task){
        try {
            workQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //內部類WorkThread,模擬線程池中的工作線程
    //主要的作用就是消費workQueue中的任務,并執行
    //由于工作線程需要不斷從workQueue中獲取任務,使用了while(true)循環不斷嘗試消費隊列中的任務
    class WorkThread extends Thread{
        @Override
        public void run() {
            //不斷循環獲取隊列中的任務
            while (true){
                //當沒有任務時,會阻塞
                try {
                    Runnable workTask = workQueue.take();
                    workTask.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

沒錯,我們僅僅用了幾十行Java代碼就實現了一個極簡版的Java線程池,沒錯,這個極簡版的Java線程池的代碼卻體現了Java線程池的核心原理。

接下來,我們測試下這個極簡版的Java線程池。

編寫測試程序

測試程序也比較簡單,就是通過在main()方法中調用ThreadPool類的構造方法,傳入線程池的大小,創建一個ThreadPool類的實例,然后循環10次調用ThreadPool類的execute()方法,向線程池中提交的任務為:打印當前線程的名稱--->> Hello ThreadPool

整體測試代碼如下所示。

package io.binghe.thread.pool.test;

import io.binghe.thread.pool.ThreadPool;

import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 測試自定義線程池
 */
public class ThreadPoolTest {

    public static void main(String[] args){
        ThreadPool threadPool = new ThreadPool(10);
        IntStream.range(0, 10).forEach((i) -> {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "--->> Hello ThreadPool");
            });
        });
    }
}

接下來,運行ThreadPoolTest類的main()方法,會輸出如下信息。

Thread-0--->> Hello ThreadPool
Thread-9--->> Hello ThreadPool
Thread-5--->> Hello ThreadPool
Thread-8--->> Hello ThreadPool
Thread-4--->> Hello ThreadPool
Thread-1--->> Hello ThreadPool
Thread-2--->> Hello ThreadPool
Thread-5--->> Hello ThreadPool
Thread-9--->> Hello ThreadPool
Thread-0--->> Hello ThreadPool

以上就是關于“Java線程池代碼怎么寫”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玛多县| 罗定市| 奉节县| 奇台县| 巨鹿县| 武川县| 广安市| 江山市| 合水县| 龙岩市| 柯坪县| 勃利县| 大埔县| 陇西县| 贵南县| 九台市| 凤台县| 吉首市| 宾阳县| 纳雍县| 黄平县| 炉霍县| 黔江区| 巴南区| 电白县| 韶山市| 德清县| 新闻| 泾阳县| 云阳县| 民权县| 法库县| 临城县| 南川市| 太谷县| 弥勒县| 通化县| 泸定县| 巨鹿县| 宜春市| 江安县|