本篇內容介紹了“Java的Executor線程池框架怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
創(chuàng)新互聯(lián)公司長期為成百上千客戶提供的網站建設服務,團隊從業(yè)經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網生態(tài)環(huán)境。為惠陽企業(yè)提供專業(yè)的成都做網站、成都網站建設,惠陽網站改版等技術服務。擁有10多年豐富建站經驗和眾多成功案例,為您定制開發(fā)。
Executor系統(tǒng)中,將線程任務提交和任務執(zhí)行進行了解耦的設計,Executor有各種功能強大的實現(xiàn)類,提供便捷方式來提交任務并且獲取任務執(zhí)行結果,封裝了任務執(zhí)行的過程,不再需要Thread().start()方式,顯式創(chuàng)建線程并關聯(lián)執(zhí)行任務。
線程被一對一映射為服務所在操作系統(tǒng)線程,啟動時會創(chuàng)建一個操作系統(tǒng)線程;當該線程終止時,這個操作系統(tǒng)線程也會被回收。
Executor框架包含的核心接口和主要的實現(xiàn)類如下圖所示:
線程池任務:核心接口:Runnable、Callable接口和接口實現(xiàn)類;
任務的結果:接口Future和實現(xiàn)類FutureTask;
任務的執(zhí)行:核心接口Executor和ExecutorService接口。在Executor框架中有兩個核心類實現(xiàn)了ExecutorService接口,ThreadPoolExecutor和ScheduledThreadPoolExecutor。
ThreadPoolExecutor基礎構造
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {}
參數名 | 說明 |
---|---|
corePoolSize | 線程池的核心大小,隊列沒滿時,線程最大并發(fā)數 |
maximumPoolSize | 最大線程池大小,隊列滿后線程能夠容忍的最大并發(fā)數 |
keepAliveTime | 空閑線程等待回收的時間限制 |
unit | keepAliveTime時間單位 |
workQueue | 阻塞的隊列類型 |
threadFactory | 創(chuàng)建線程的工廠,一般用默認即可 |
handler | 超出工作隊列和線程池時,任務會默認拋出異常 |
ExecutorService :Executors.newFixedThreadPool(); ExecutorService :Executors.newSingleThreadExecutor(); ExecutorService :Executors.newCachedThreadPool(); ThreadPoolExecutor :new ThreadPoolExecutor() ;
通常情況下,線程池不允許使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式,這樣的處理方式更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風險。
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)); } } } // 定義線程池任務 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(); } }
流程分析
線程池中線程數小于corePoolSize時,新任務將創(chuàng)建一個新線程執(zhí)行任務,不論此時線程池中存在空閑線程;
線程池中線程數達到corePoolSize時,新任務將被放入workQueue中,等待線程池中任務調度執(zhí)行;
當workQueue已滿,且maximumPoolSize>corePoolSize時,新任務會創(chuàng)建新線程執(zhí)行任務;
當workQueue已滿,且提交任務數超過maximumPoolSize,任務由RejectedExecutionHandler處理;
當線程池中線程數超過corePoolSize,且超過這部分的空閑時間達到keepAliveTime時,回收該線程;
如果設置allowCoreThreadTimeOut(true)時,線程池中corePoolSize范圍內的線程空閑時間達到keepAliveTime也將回收;
應用場景:批量賬戶和密碼的校驗任務,在實際的業(yè)務中算比較常見的,通過初始化線程池,把任務提交執(zhí)行,最后拿到處理結果,這就是線程池使用的核心思想:節(jié)省資源提升效率。
public class Executor02 { public static void main(String[] args) { // 初始化校驗任務 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(); } // 查看結果 for (Future<Boolean> result : results){ try { System.out.println(result.get()); // System.out.println(result.get(10000,TimeUnit.SECONDS)); } catch (Exception e) { e.printStackTrace() ; } } // 關閉線程池 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")) ; } } // 校驗任務 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 { // 校驗賬戶+密碼 if (userName.equals("root") && passWord.equals("123")){ return Boolean.TRUE ; } return Boolean.FALSE ; } }
線程池主要用來解決線程生命周期開銷問題和資源不足問題,通過線程池對多個任務線程重復使用,線程創(chuàng)建也被分攤到多個任務上,多數任務提交就有空閑的線程可以使用,所以消除線程頻繁創(chuàng)建帶來的開銷。
“Java的Executor線程池框架怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注創(chuàng)新互聯(lián)網站,小編將為大家輸出更多高質量的實用文章!
當前名稱:Java的Executor線程池框架怎么使用
標題鏈接:http://jinyejixie.com/article10/pspjgo.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供服務器托管、移動網站建設、外貿網站建設、網站維護、虛擬主機、定制網站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)