溫馨提示×

溫馨提示×

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

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

Java的Executor線程池框架怎么使用

發(fā)布時(shí)間:2021-11-30 14:23:42 來源:億速云 閱讀:168 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“Java的Executor線程池框架怎么使用”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

一、Executor框架簡介

1、基礎(chǔ)簡介

Executor系統(tǒng)中,將線程任務(wù)提交和任務(wù)執(zhí)行進(jìn)行了解耦的設(shè)計(jì),Executor有各種功能強(qiáng)大的實(shí)現(xiàn)類,提供便捷方式來提交任務(wù)并且獲取任務(wù)執(zhí)行結(jié)果,封裝了任務(wù)執(zhí)行的過程,不再需要Thread().start()方式,顯式創(chuàng)建線程并關(guān)聯(lián)執(zhí)行任務(wù)。

2、調(diào)度模型

線程被一對一映射為服務(wù)所在操作系統(tǒng)線程,啟動(dòng)時(shí)會創(chuàng)建一個(gè)操作系統(tǒng)線程;當(dāng)該線程終止時(shí),這個(gè)操作系統(tǒng)線程也會被回收。

Java的Executor線程池框架怎么使用

3、核心API結(jié)構(gòu)

Executor框架包含的核心接口和主要的實(shí)現(xiàn)類如下圖所示:

Java的Executor線程池框架怎么使用

線程池任務(wù):核心接口:Runnable、Callable接口和接口實(shí)現(xiàn)類;

任務(wù)的結(jié)果:接口Future和實(shí)現(xiàn)類FutureTask;

任務(wù)的執(zhí)行:核心接口Executor和ExecutorService接口。在Executor框架中有兩個(gè)核心類實(shí)現(xiàn)了ExecutorService接口,ThreadPoolExecutor和ScheduledThreadPoolExecutor。

二、用法案例

1、API基礎(chǔ)

ThreadPoolExecutor基礎(chǔ)構(gòu)造

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {}
參數(shù)名說明
corePoolSize線程池的核心大小,隊(duì)列沒滿時(shí),線程最大并發(fā)數(shù)
maximumPoolSize最大線程池大小,隊(duì)列滿后線程能夠容忍的最大并發(fā)數(shù)
keepAliveTime空閑線程等待回收的時(shí)間限制
unitkeepAliveTime時(shí)間單位
workQueue阻塞的隊(duì)列類型
threadFactory創(chuàng)建線程的工廠,一般用默認(rèn)即可
handler超出工作隊(duì)列和線程池時(shí),任務(wù)會默認(rèn)拋出異常

2、初始化方法

ExecutorService :Executors.newFixedThreadPool();
ExecutorService :Executors.newSingleThreadExecutor();
ExecutorService :Executors.newCachedThreadPool();

ThreadPoolExecutor :new ThreadPoolExecutor() ;

通常情況下,線程池不允許使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式,這樣的處理方式更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。

3、基礎(chǔ)案例

package com.multy.thread.block08executor;
import java.util.concurrent.*;

public class Executor01 {
    // 定義線程池
    private static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                    3,10,5000,TimeUnit.SECONDS,
                    new SynchronousQueue<>(),Executors.defaultThreadFactory(),new ExeHandler());
    public static void main(String[] args) {
        for (int i = 0 ; i < 100 ; i++){
            poolExecutor.execute(new PoolTask(i));
            //帶返回值:poolExecutor.submit(new PoolTask(i));
        }
    }
}
// 定義線程池任務(wù)
class PoolTask implements Runnable {

    private int numParam;

    public PoolTask (int numParam) {
        this.numParam = numParam;
    }
    @Override
    public void run() {
        try {
            System.out.println("PoolTask "+ numParam+" begin...");
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public int getNumParam() {
        return numParam;
    }
    public void setNumParam(int numParam) {
        this.numParam = numParam;
    }
}
// 定義異常處理
class ExeHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
        System.out.println("ExeHandler "+executor.getCorePoolSize());
        executor.shutdown();
    }
}

流程分析

  • 線程池中線程數(shù)小于corePoolSize時(shí),新任務(wù)將創(chuàng)建一個(gè)新線程執(zhí)行任務(wù),不論此時(shí)線程池中存在空閑線程;

  • 線程池中線程數(shù)達(dá)到corePoolSize時(shí),新任務(wù)將被放入workQueue中,等待線程池中任務(wù)調(diào)度執(zhí)行;

  • 當(dāng)workQueue已滿,且maximumPoolSize>corePoolSize時(shí),新任務(wù)會創(chuàng)建新線程執(zhí)行任務(wù);

  • 當(dāng)workQueue已滿,且提交任務(wù)數(shù)超過maximumPoolSize,任務(wù)由RejectedExecutionHandler處理;

  • 當(dāng)線程池中線程數(shù)超過corePoolSize,且超過這部分的空閑時(shí)間達(dá)到keepAliveTime時(shí),回收該線程;

  • 如果設(shè)置allowCoreThreadTimeOut(true)時(shí),線程池中corePoolSize范圍內(nèi)的線程空閑時(shí)間達(dá)到keepAliveTime也將回收;

三、線程池應(yīng)用

應(yīng)用場景:批量賬戶和密碼的校驗(yàn)任務(wù),在實(shí)際的業(yè)務(wù)中算比較常見的,通過初始化線程池,把任務(wù)提交執(zhí)行,最后拿到處理結(jié)果,這就是線程池使用的核心思想:節(jié)省資源提升效率。

public class Executor02 {

    public static void main(String[] args) {
        // 初始化校驗(yàn)任務(wù)
        List<CheckTask> checkTaskList = new ArrayList<>() ;
        initList(checkTaskList);
        // 定義線程池
        ExecutorService executorService ;
        if (checkTaskList.size() < 10){
            executorService = Executors.newFixedThreadPool(checkTaskList.size());
        }else{
            executorService = Executors.newFixedThreadPool(10);
        }
        // 批量處理
        List<Future<Boolean>> results = new ArrayList<>() ;
        try {
            results = executorService.invokeAll(checkTaskList);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        // 查看結(jié)果
        for (Future<Boolean> result : results){
            try {
                System.out.println(result.get());
                // System.out.println(result.get(10000,TimeUnit.SECONDS));
            } catch (Exception e) {
                e.printStackTrace() ;
            }
        }
        // 關(guān)閉線程池
        executorService.shutdownNow();
    }

    private static void initList (List<CheckTask> checkTaskList){
        checkTaskList.add(new CheckTask("root","123")) ;
        checkTaskList.add(new CheckTask("root1","1234")) ;
        checkTaskList.add(new CheckTask("root2","1235")) ;
    }
}
// 校驗(yàn)任務(wù)
class CheckTask implements Callable<Boolean> {
    private String userName ;
    private String passWord ;
    public CheckTask(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
    }
    @Override
    public Boolean call() throws Exception {
        // 校驗(yàn)賬戶+密碼
        if (userName.equals("root") && passWord.equals("123")){
            return Boolean.TRUE ;
        }
        return Boolean.FALSE ;
    }
}

線程池主要用來解決線程生命周期開銷問題和資源不足問題,通過線程池對多個(gè)任務(wù)線程重復(fù)使用,線程創(chuàng)建也被分?jǐn)偟蕉鄠€(gè)任務(wù)上,多數(shù)任務(wù)提交就有空閑的線程可以使用,所以消除線程頻繁創(chuàng)建帶來的開銷。

“Java的Executor線程池框架怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI