資源描述:
《聊聊并發(fā)(3):java線程池的分析和使用-java開發(fā)java經(jīng)驗技巧》由會員上傳分享,免費在線閱讀,更多相關內(nèi)容在工程資料-天天文庫。
1、聊聊并發(fā)(3):Java線程池的分析和使用-編程開發(fā)技術聊聊并發(fā)(3):Java線程池的分析和使用原文出處:方騰E本系列:聊聊并發(fā)(1)深入分析Volatile的實現(xiàn)原理聊聊并發(fā)(2)JavaSE1.6中的Synchronized1????引言合理利用線程池能夠帶來三個好處。第一:降低資源消耗。通過重復利用己創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗。第二:提高響應速度。當任務到達吋,任務口J以不需要的等到線程創(chuàng)建就能立即執(zhí)行。第三:提高線程的口J管理性。線程是稀缺資源,如杲無限制的創(chuàng)建,不僅會消耗系統(tǒng)資源,還會降低系統(tǒng)的穩(wěn)定性,使用
2、線程池可以進行統(tǒng)一的分配,調(diào)優(yōu)和監(jiān)控。但是要做到合理的利用線程池,必須對其原理了如指掌。2.線程池的使用線程池的創(chuàng)建我們可以通過ThreadPoolExecutor來創(chuàng)建一個線程池。newThreadPoolExecutor(corePoolSize,maximumPoo1Size,kccpAlivcTime,mi11iseconds,runnablcTaskQucuc,thrcadFactory,handler);創(chuàng)建一個線程池需要輸入兒個參數(shù):?corePoolSize(線程池的基本大小):當提交一個任務到線程池時,線程池會創(chuàng)
3、建-一個線程來執(zhí)行任務,即使其他空閑的基本線程能夠執(zhí)行新任務也會創(chuàng)建線程,等到需要執(zhí)行的任務數(shù)人于線程池基木人小時就不再創(chuàng)建。如果調(diào)用了線程池的prestartAIICoreThreads方法,線程池會提前創(chuàng)建并啟動所有基本線程。?runnablcTaskQucuc(任務隊列):用于保存等待執(zhí)行的任務的阻塞隊列??梢赃x擇以下幾個阻塞隊列。1.ArrayBlockingQueue:是一個基于數(shù)組結構的冇界阻塞隊列,此隊列按FIFO(先進先出)原則對元素進行排序。2.LinkedBlockingQueue:一個基于鏈表結構的阻塞隊列,
4、此隊列按FIFO(先進先出)排序元索,吞吐量通常要高于ArrayBlockingQueue□靜態(tài)工廠方法Executors.newFixedThreadPool()使用了這個隊列。3.SynchronousQueue:一個不存儲元素的阻塞隊列。每個插入操作必須等到另一個線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài),吞吐量通常耍鬲于LinkedBlockingQueue,靜態(tài)IJ方法Executors.newCachedThreadPool使用了這個隊列。4.PriorityBlockingQueue:一個具冇優(yōu)先級得無限阻塞隊列
5、。?maximumPoolSize(線程池最人人?。壕€程池允許創(chuàng)建的最人線程數(shù)。如果隊列滿了,并且己創(chuàng)建的線程數(shù)小于最大線程數(shù),則線程池會再創(chuàng)建新的線程執(zhí)行任務。值得注意的是如果使用了無界的任務隊列這個參數(shù)就沒什么效果。?ThreadFactory:用于設置創(chuàng)建線程的工廠,可以通過線程工廠給每個創(chuàng)建出來的線程設置更有意義的名字,Debug和定位問題吋非常又幫助。RejectedExecutionHandler(飽和策略):當隊列和線程池都滿了,說明線程池處于飽和狀態(tài),那么必須采取一種策略處理提交的新任務。這個策略默認情況下是Ab
6、ortPolicy,表示無法處理新任務時拋出異常。以下是JDK1.5提供的四種策略。n?AbortPolicy:直接拋出異常。1.CallerRunsPolicy:只用調(diào)用者所在線程來運行任務。2.DiscardOldestPolicy:丟棄隊列里最近的一個任務,并執(zhí)行當前任務。3.DiscardPolicy:不處理,丟棄掉。4.當然也可以根據(jù)應用場景需要來實現(xiàn)RejectedExecutionHandler接口自定義策略。如記錄H志或持久化不能處理的任務。?keepAIiveTime(線程活動保持時間):線程池的工作線程空閑后,
7、保持存活的時間。所以如果任務很多,并且每個任務執(zhí)行的時間比較短,可以調(diào)大這個時間,提高線程的利用率。?TimeUnit(線程活動保持時間的單位):XT選的單位有天(DAYS),小時(HOURS),分鐘(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS,T分毫秒)和毫微秒(NANOSECONDS,千分Z—微秒)。向線程池提交任務我們口J以使用execute提交的任務,但是execute方法沒冇返回值,所以無法判斷任務知否被線程池執(zhí)行成功。通過以下代碼可知execute方法輸入的任務是一個Runnab
8、le類的實例。threadsPool?execute(newRunnable(){?Overridepublicvoidrun(){//TODOAuto-generatedmethodstub}});我們也口J以使用submit?方法來提交任務,它