多線程編程(五)--線程池,多線程編程--線程池
JDK 1.5之後加入了Java.util.concurrent包,這個包中主要介紹java中線程以及線程池的使用。為我們在開發中處理線程的問題提供了非常大的協助。
一、池的由來
拿資料庫來舉例子:每當一個請求到達就建立一個新的連結,但當有大量請求並發訪問時,就會不斷地建立和銷毀連結,開銷很大。為了提高效率,達到複用的效果,就有了池的概念。
線程池是預先建立線程的一種技術。線程池在任務還沒到來之前先建立一定數量的線程,放入空閑隊列中。這些線程都是處於睡眠狀態,即均為啟動,不消耗CPU,而只是佔用較小的記憶體空間。當請求到來之後,緩衝池給這次請求分配一個空閑線程,把請求傳入此線程中運行,進行處理。當預先建立的線程都處於運行狀態,即預製線程不夠,線程池可以自由建立一定數量的新線程,用於處理更多的請求。當系統比較閑的時候,也可以通過移除一部分一直處於停用狀態的線程。
二、使用線程池的好處
1、減少了建立和銷毀線程的次數,達到最大程度的複用對象
2、線程代碼和業務代碼分離
三、線程池使用
Java裡麵線程池的頂級介面是Executor,但是嚴格意義上講Executor並不是一個線程池,而只是一個執行線程的工具。真正的線程池介面是ExecutorService。
1、固定線程池
ExecutorServicethreadPool = Executors.newFixedThreadPool(3);// 建立可以容納3個線程的線程池
2、緩衝的線程池
ExecutorServicethreadPool = Executors.newCachedThreadPool();// 線程池的大小會根據執行的任務數動態分配
3、單一線程池
ExecutorServicethreadPool = Executors.newSingleThreadExecutor();//池子裡面只有一個線程,好處是如果池子裡面的線程死掉,它會再啟動一個線程所以實現了線程死後重啟一個線程
代碼:
public static voidmain(String[] args) {//固定的線程池ExecutorServicethreadPool = Executors.newFixedThreadPool(3); //緩衝的線程池// ExecutorServicethreadPool = Executors.newCachedThreadPool(); //池子裡面只有一個線程,好處是如果池子裡面的線程死掉,它會再啟動一個線程所以實現了線程死後重啟一個線程// ExecutorServicethreadPool = Executors.newSingleThreadExecutor(); for(int i = 1; i <= 10; i++) {finalint task = i;threadPool.execute(newRunnable() {@Overridepublicvoid run() {for(int j = 1; j < 10; j++) {try{Thread.sleep(20);}catch (InterruptedException e) {//TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+" is looping of " + j + " for task of " + task);}}});}System.out.println("allof 10 task have committed! ");//6s以後炸,每隔2S炸一下Executors.newScheduledThreadPool(3).scheduleAtFixedRate(newRunnable(){@Overridepublicvoid run() {System.out.println("bombing"); }}, 6,2, TimeUnit.SECONDS); //6s以後炸,每隔2S炸一下} }
運行效果:
固定線程:
當前設定了三個線程,故這三個線程在工作。FixedThreadPool中,有一個固定大小的池,如果當前需要執行的任務超過了池大小,那麼多餘的任務等待狀態,直到有空閑下來的線程執行任務,而當執行的任務小於池大小,閒置線程也不會去銷毀。如果某個線程因為執行異常而結束,那麼線程池會補充一個新線程。
緩衝線程:
這幾個線程是交替工作的,CachedThreadPool會建立一個緩衝區,將初始化的線程緩衝起來,如果線程池的大小超過了處理任務所需要的線程,那麼就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能添加新線程來處理任務。此線程池也不會對線程池大小做限制,線程池大小完全依賴於作業系統(或者說JVM)能夠建立的最大線程大小。
單個線程池
只有一個線程在工作。此線程池保證所有任務的執行順序按照任務的提交順序執行。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。