㈠ java面試之線程池參數設置
在Java中,提供多種線程池類型,以滿足不同任務需求。常用類型包括:
緩存線程池(Executors.newCachedThreadPool):動態創建線程,根據任務數量調整大小。
定時線程池(Executors.newScheledThreadPool):按固定時間間隔或延遲執行任務。
固定線程池(Executors.newFixedThreadPool):維護固定數量線程,任務入隊等待。
單線程線程池(Executors.newSingleThreadExecutor):包含一個線程,任務順序執行。
工作竊取線程池(Executors.newWorkStealingPool):內部使用ForkJoinPool,適用於多線程並行操作。
這些線程池都是通過Executors類創建的,但推薦使用ThreadPoolExecutor自定義參數。關鍵參數包括:
核心線程數量(corePoolSize):線程池中保持的最少線程數。
最大線程數量(maximumPoolSize):線程池能容納的最大線程數。
存活時間(keepAliveTime):線程閑置時間超過此值將被銷毀。
存活時間單位(TimeUnit):keepAliveTime的時間單位。
阻塞隊列(workQueue):保存待執行任務。
線程創建工廠(ThreadFactory):自定義線程屬性。
飽和策略(RejectedExecutionHandler):隊列滿時,決定如何處理新任務。
配置參數時,考慮任務類型、CPU核數等,有經驗值、最佳線程數演算法等方法。經驗值法考慮任務密集度,IO密集型設置為2N,CPU密集型設置為N+1;最佳線程數演算法則綜合任務等待與執行時間。Java並發編程實踐與Java虛擬機提供不同計算方法,旨在優化線程池性能。
實際應用中,需綜合分析任務特性、系統負載等,通過實驗與調整找到平衡點。監測工具與基準負載測試有助於確定線程池最優大小,實現資源高效利用。
㈡ java常用的幾種線程池實例講解
下面給你介紹4種線程池:
1、newCachedThreadPool:
底層:返回ThreadPoolExecutor實例,corePoolSize為0;maximumPoolSize為Integer.MAX_VALUE;keepAliveTime為60L;unit為TimeUnit.SECONDS;workQueue為SynchronousQueue(同步隊列)
通俗:當有新任務到來,則插入到SynchronousQueue中,由於SynchronousQueue是同步隊列,因此會在池中尋找可用線程來執行,若有可以線程則執行,若沒有可用線程則創建一個線程來執行該任務;若池中線程空閑時間超過指定大小,則該線程會被銷毀。
適用:執行很多短期非同步的小程序或者負載較輕的伺服器
2、newFixedThreadPool:
底層:返回ThreadPoolExecutor實例,接收參數為所設定線程數量nThread,corePoolSize為nThread,maximumPoolSize為nThread;keepAliveTime為0L(不限時);unit為:TimeUnit.MILLISECONDS;WorkQueue為:new LinkedBlockingQueue<Runnable>()無解阻塞隊列
通俗:創建可容納固定數量線程的池子,每隔線程的存活時間是無限的,當池子滿了就不在添加線程了;如果池中的所有線程均在繁忙狀態,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
適用:執行長期的任務,性能好很多
3、newSingleThreadExecutor
底層:包裝的ThreadPoolExecutor實例,corePoolSize為1;maximumPoolSize為1;keepAliveTime為0L;unit為:TimeUnit.MILLISECONDS;workQueue為:new LinkedBlockingQueue<Runnable>()無解阻塞隊列
通俗:創建只有一個線程的線程池,且線程的存活時間是無限的;當該線程正繁忙時,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
適用:一個任務一個任務執行的場景
4、NewScheledThreadPool:
底層:創建ScheledThreadPoolExecutor實例,corePoolSize為傳遞來的參數,maximumPoolSize為Integer.MAX_VALUE;keepAliveTime為0;unit為:TimeUnit.NANOSECONDS;workQueue為:new DelayedWorkQueue()一個按超時時間升序排序的隊列
通俗:創建一個固定大小的線程池,線程池內線程存活時間無限制,線程池可以支持定時及周期性任務執行,如果所有線程均處於繁忙狀態,對於新任務會進入DelayedWorkQueue隊列中,這是一種按照超時時間排序的隊列結構
適用:周期性執行任務的場景
最後給你說一下線程池任務執行流程:
當線程池小於corePoolSize時,新提交任務將創建一個新線程執行任務,即使此時線程池中存在空閑線程。
當線程池達到corePoolSize時,新提交任務將被放入workQueue中,等待線程池中任務調度執行
當workQueue已滿,且maximumPoolSize>corePoolSize時,新提交任務會創建新線程執行任務
當提交任務數超過maximumPoolSize時,新提交任務由RejectedExecutionHandler處理
當線程池中超過corePoolSize線程,空閑時間達到keepAliveTime時,關閉空閑線程
當設置allowCoreThreadTimeOut(true)時,線程池中corePoolSize線程空閑時間達到keepAliveTime也將關閉
㈢ java線程池(一):java線程池基本使用及Executors
@[toc] 在前面學習線程組的時候就提到過線程池。實際上線程組在我們的日常工作中已經不太會用到,但是線程池恰恰相反,是我們日常工作中必不可少的工具之一。現在開始對線程池的使用,以及底層ThreadPoolExecutor的源碼進行分析。
1.為什麼需要線程池我們在前面對線程基礎以及線程的生命周期有過詳細介紹。一個基本的常識就是,線程是一個特殊的對象,其底層是依賴於JVM的native方法,在jvm虛擬機內部實現的。線程與普通對象不一樣的地方在於,除了需要在堆上分配對象之外,還需要給每個線程分配一個線程棧、以及本地方法棧、程序計數器等線程的私有空間。線程的初始化工作相對於線程執行的大多數任務而言,都是一個耗時比較長的工作。這與資料庫使用一樣。有時候我們連接資料庫,僅僅只是為了執行一條很小的sql語句。但是在我們日常的開發工作中,我們的絕大部分工作內容,都會分解為一個個短小的執行任務來執行。這樣才能更加合理的復用資源。這種思想就與我們之前提到的協程一樣。任務要盡可能的小。但是在java中,任務不可能像協程那樣拆分得那麼細。那麼試想,如果說,有一個已經初始化好的很多線程,在隨時待命,那麼當我們有任務提交的時候,這些線程就可以立即工作,無縫接管我們的任務請求。那麼效率就會大大增加。這些個線程可以處理任何任務。這樣一來我們就把實際的任務與線程本身進行了解耦。從而將這些線程實現了復用。 這種復用的一次創建,可以重復使用的池化的線程對象就被成為線程池。 在線程池中,我們的線程是可以復用的,不用每次都創建一個新的線程。減少了創建和銷毀線程的時間開銷。 同時,線程池還具有隊列緩沖策略,拒絕機制和動態線程管理。可以實現線程環境的隔離。當一個線程有問題的時候,也不會對其他的線程造成影響。 以上就是我們使用線程池的原因。一句話來概括就是資源復用,降低開銷。
2.java中線程池的實現在java中,線程池的主要介面是Executor和ExecutorService在這兩個介面中分別對線程池的行為進行了約束,最主要的是在ExecutorService。之後,線程池的實際實現類是AbstractExecutorService類。這個類有三個主要的實現類,ThreadpoolExecutorService、ForkJoinPool以及DelegatedExecutorService。
後面我們將對這三種最主要的實現類的源碼以及實現機制進行分析。
3.創建線程的工廠方法Executors在java中, 已經給我們提供了創建線程池的工廠方法類Executors。通過這個類以靜態方法的模式可以為我們創建大多數線程池。Executors提供了5種創建線程池的方式,我們先來看看這個類提供的工廠方法。
3.1 newFixedThreadPool/** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue.At any point, at most * {@code nThreads} threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates e to a failure ring execution * prior to shutdown, a new one will take its place if needed to * execute subsequent tasks.The threads in the pool will exist * until it is explicitly {@link ExecutorService#shutdown shutdown}. * * @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if {@code nThreads <= 0} */public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}這個方法能夠創建一個固定線程數量的無界隊列的線程池。參數nthreads是最多可同時處理的活動的線程數。如果在所有線程都在處理任務的情況下,提交了其他的任務,那麼這些任務將處於等待隊列中。直到有一個線程可用為止。如果任何線程在關閉之前的執行過程中,由於失敗而終止,則需要在執行後續任務的時候,創建一個新的線程來替換。線程池中的所有線程都將一直存在,直到顯示的調用了shutdown方法。 上述方法能創建一個固定線程數量的線程池。內部默認的是使用LinkedBlockingQueue。但是需要注意的是,這個LinkedBlockingQueue底層是鏈表結構,其允許的最大隊列長度為Integer.MAX_VALUE。
public LinkedBlockingQueue() {this(Integer.MAX_VALUE);}這樣在使用的過程中如果我們沒有很好的控制,那麼就可能導致內存溢出,出現OOM異常。因此這種方式實際上已經不被提倡。我們在使用的過程中應該謹慎使用。 newFixedThreadPool(int nThreads, ThreadFactory threadFactory)方法:
/** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue, using the provided * ThreadFactory to create new threads when needed.At any point, * at most {@code nThreads} threads will be active processing * tasks.If additional tasks are submitted when all threads are * active, they will wait in the queue until a thread is * available.If any thread terminates e to a failure ring * execution prior to shutdown, a new one will take its place if * needed to execute subsequent tasks.The threads in the pool will * exist until it is explicitly {@link ExecutorService#shutdown * shutdown}. * * @param nThreads the number of threads in the pool * @param threadFactory the factory to use when creating new threads * @return the newly created thread pool * @throws NullPointerException if threadFactory is null * @throws IllegalArgumentException if {@code nThreads <= 0} */public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory);}這個方法與3.1中newFixedThreadPool(int nThreads)的方法的唯一區別就是,增加了threadFactory參數。在前面方法中,對於線程的創建是採用的默認實現Executors.defaultThreadFactory()。而在此方法中,可以根據需要自行定製。
3.2 newSingleThreadExecutor/** * Creates an Executor that uses a single worker thread operating * off an unbounded queue. (Note however that if this single * thread terminates e to a failure ring execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.)Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * {@code newFixedThreadPool(1)} the returned executor is * guaranteed not to be reconfigurable to use additional threads. * * @return the newly created single-threaded Executor */public static ExecutorService newSingleThreadExecutor() {return new (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}此方法將會創建指有一個線程和一個無屆隊列的線程池。需要注意的是,如果這個執行線程在執行過程中由於失敗而終止,那麼需要在執行後續任務的時候,用一個新的線程來替換。 那麼這樣一來,上述線程池就能確保任務的順序性,並且在任何時間都不會有多個線程處於活動狀態。與newFixedThreadPool(1)不同的是,使用newSingleThreadExecutor返回的ExecutorService不能被重新分配線程數量。而使用newFixExecutor(1)返回的ExecutorService,其活動的線程的數量可以重新分配。後面專門對這個問題進行詳細分析。 newSingleThreadExecutor(ThreadFactory threadFactory) 方法:
/** * Creates an Executor that uses a single worker thread operating * off an unbounded queue, and uses the provided ThreadFactory to * create a new thread when needed. Unlike the otherwise * equivalent {@code newFixedThreadPool(1, threadFactory)} the * returned executor is guaranteed not to be reconfigurable to use * additional threads. * * @param threadFactory the factory to use when creating new * threads * * @return the newly created single-threaded Executor * @throws NullPointerException if threadFactory is null */public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {return new (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory));}這個方法與3.3中newSingleThreadExecutor的區別就在於增加了一個threadFactory。可以自定義創建線程的方法。
3.3 newCachedThreadPool/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available.These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. * Calls to {@code execute} will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from * the cache. Thus, a pool that remains idle for long enough will * not consume any resources. Note that pools with similar * properties but different details (for example, timeout parameters) * may be created using {@link ThreadPoolExecutor} constructors. * * @return the newly created thread pool */public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}這個方法用來創建一個線程池,該線程池可以根據需要自動增加線程。以前的線程也可以復用。這個線程池通常可以提高很多執行周期短的非同步任務的性能。對於execute將重用以前的構造線程。如果沒有可用的線程,就創建一個 新的線程添加到pool中。60秒內,如果該線程沒有被使用,則該線程將會終止,並從緩存中刪除。因此,在足夠長的時間內,這個線程池不會消耗任何資源。可以使用ThreadPoolExecutor構造函數創建具有類似屬性但是詳細信息不同的線程池。 ?需要注意的是,這個方法創建的線程池,雖然隊列的長度可控,但是線程的數量的范圍是Integer.MAX_VALUE。這樣的話,如果使用不當,同樣存在OOM的風險。比如說,我們使用的每個任務的耗時比較長,任務的請求又非常快,那麼這樣勢必會造成在單位時間內創建了大量的線程。從而造成內存溢出。 newCachedThreadPool(ThreadFactory threadFactory)方法:
/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available, and uses the provided * ThreadFactory to create new threads when needed. * @param threadFactory the factory to use when creating new threads * @return the newly created thread pool * @throws NullPointerException if threadFactory is null */public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>(),threadFactory);}這個方法區別同樣也是在於,增加了threadFactory可以自行指定線程的創建方式。
2.4 newScheledThreadPool/** * Creates a thread pool that can schele commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, * even if they are idle * @return a newly created scheled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} */public static ScheledExecutorService newScheledThreadPool(int corePoolSize) {return new ScheledThreadPoolExecutor(corePoolSize);}創建一個線程池,該線程池可以將任務在指定的延遲時間之後運行。或者定期運行。這個方法返回的是ScheledThreadPoolExecutor。這個類是ThreadPoolExecutor的子類。在原有線程池的的基礎之上,增加了延遲和定時功能。我們在後面分析了ThreadPoolExecutor源碼之後,再來分析這個類的源碼。 與之類似的方法:
/** * Creates a thread pool that can schele commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, * even if they are idle * @param threadFactory the factory to use when the executor * creates a new thread * @return a newly created scheled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} * @throws NullPointerException if threadFactory is null */public static ScheledExecutorService newScheledThreadPool(int corePoolSize, ThreadFactory threadFactory) {return new ScheledThreadPoolExecutor(corePoolSize, threadFactory);}通過這個方法,我們可以指定threadFactory。自定義線程創建的方式。 同樣,我們還可以只指定一個線程:
public static ScheledExecutorService () {return new (new ScheledThreadPoolExecutor(1));}public static ScheledExecutorService (ThreadFactory threadFactory) {return new (new ScheledThreadPoolExecutor(1, threadFactory));}上述兩個方法都可以實現這個功能,但是需要注意的是,這兩個方法的返回在外層包裹了一個包裝類。
3.5 newWorkStealingPool這種方式是在jdk1.8之後新增的。我們先來看看其源碼:
public LinkedBlockingQueue() {this(Integer.MAX_VALUE);}0這個方法實際上返回的是ForkJoinPool。該方法創建了一
㈣ Java實現通用線程池
線程池通俗的描述就是預先創建若干空閑線程 等到需要用多線程去處理事務的時候去喚醒某些空閑線程執行處理任務 這樣就省去了頻繁創建線程的時間 因為頻 繁創建線程是要耗費大量的CPU資源的 如果一個應用程序需要頻繁地處理大量並發事務 不斷的創建銷毀線程往往會大大地降低系統的效率 這時候線程池就派 上用場了
本文旨在使用Java語言編寫一個通用的線程池 當需要使用線程池處理事務時 只需按照指定規范封裝好事務處理對象 然後用已有的線程池對象去自動選擇空 閑線程自動調用事務處理對象即可 並實現線程池的動態修改(修改當前線程數 最大線程數等) 下面是實現代碼
//ThreadTask java
package polarman threadpool;
/** *//**
*線程任務
* @author ryang
*
*/
public interface ThreadTask {
public void run();
}
//PooledThread java
package polarman threadpool;
import java util Collection; import java util Vector;
/** *//**
*接受線程池管理的線程
* @author ryang
*
*/
public class PooledThread extends Thread {
protected Vector tasks = new Vector();
protected boolean running = false;
protected boolean stopped = false;
protected boolean paused = false;
protected boolean killed = false;
private ThreadPool pool;
public PooledThread(ThreadPool pool) { this pool = pool;
}
public void putTask(ThreadTask task) { tasks add(task);
}
public void putTasks(ThreadTask[] tasks) { for(int i= ; i<tasks length; i++) this tasks add(tasks[i]);
}
public void putTasks(Collection tasks) { this tasks addAll(tasks);
}
protected ThreadTask popTask() { if(tasks size() > ) return (ThreadTask)tasks remove( );
else
return null;
}
public boolean isRunning() {
return running;
}
public void stopTasks() {
stopped = true;
}
public void stopTasksSync() {
stopTasks();
while(isRunning()) { try {
sleep( );
} catch (InterruptedException e) {
}
}
}
public void pauseTasks() {
paused = true;
}
public void pauseTasksSync() {
pauseTasks();
while(isRunning()) { try {
sleep( );
} catch (InterruptedException e) {
}
}
}
public void kill() { if(!running)
interrupt();
else
killed = true;
}
public void killSync() {
kill();
while(isAlive()) { try {
sleep( );
} catch (InterruptedException e) {
}
}
}
public synchronized void startTasks() {
running = true;
this notify();
}
public synchronized void run() { try { while(true) { if(!running || tasks size() == ) { pool notifyForIdleThread(); //System out println(Thread currentThread() getId() + : 空閑 ); this wait(); }else {
ThreadTask task;
while((task = popTask()) != null) { task run(); if(stopped) {
stopped = false;
if(tasks size() > ) { tasks clear(); System out println(Thread currentThread() getId() + : Tasks are stopped );
break;
}
}
if(paused) {
paused = false;
if(tasks size() > ) { System out println(Thread currentThread() getId() + : Tasks are paused );
break;
}
}
}
running = false;
}
if(killed) {
killed = false;
break;
}
}
}catch(InterruptedException e) {
return;
}
//System out println(Thread currentThread() getId() + : Killed );
}
}
//ThreadPool java
package polarman threadpool;
import java util Collection; import java util Iterator; import java util Vector;
/** *//**
*線程池
* @author ryang
*
*/
public class ThreadPool {
protected int maxPoolSize;
protected int initPoolSize;
protected Vector threads = new Vector();
protected boolean initialized = false;
protected boolean hasIdleThread = false;
public ThreadPool(int maxPoolSize int initPoolSize) { this maxPoolSize = maxPoolSize; this initPoolSize = initPoolSize;
}
public void init() {
initialized = true;
for(int i= ; i<initPoolSize; i++) {
PooledThread thread = new PooledThread(this);
thread start(); threads add(thread);
}
//System out println( 線程池初始化結束 線程數= + threads size() + 最大線程數= + maxPoolSize);
}
public void setMaxPoolSize(int maxPoolSize) { //System out println( 重設最大線程數 最大線程數= + maxPoolSize); this maxPoolSize = maxPoolSize;
if(maxPoolSize < getPoolSize())
setPoolSize(maxPoolSize);
}
/** *//**
*重設當前線程數
* 若需殺掉某線程 線程不會立刻殺掉 而會等到線程中的事務處理完成* 但此方法會立刻從線程池中移除該線程 不會等待事務處理結束
* @param size
*/
public void setPoolSize(int size) { if(!initialized) {
initPoolSize = size;
return;
}else if(size > getPoolSize()) { for(int i=getPoolSize(); i<size && i<maxPoolSize; i++) {
PooledThread thread = new PooledThread(this);
thread start(); threads add(thread);
}
}else if(size < getPoolSize()) { while(getPoolSize() > size) { PooledThread th = (PooledThread)threads remove( ); th kill();
}
}
//System out println( 重設線程數 線程數= + threads size());
}
public int getPoolSize() { return threads size();
}
protected void notifyForIdleThread() {
hasIdleThread = true;
}
protected boolean waitForIdleThread() {
hasIdleThread = false;
while(!hasIdleThread && getPoolSize() >= maxPoolSize) { try { Thread sleep( ); } catch (InterruptedException e) {
return false;
}
}
return true;
}
public synchronized PooledThread getIdleThread() { while(true) { for(Iterator itr=erator(); itr hasNext();) { PooledThread th = (PooledThread)itr next(); if(!th isRunning())
return th;
}
if(getPoolSize() < maxPoolSize) {
PooledThread thread = new PooledThread(this);
thread start(); threads add(thread);
return thread;
}
//System out println( 線程池已滿 等待 );
if(waitForIdleThread() == false)
return null;
}
}
public void processTask(ThreadTask task) {
PooledThread th = getIdleThread();
if(th != null) { th putTask(task); th startTasks();
}
}
public void processTasksInSingleThread(ThreadTask[] tasks) {
PooledThread th = getIdleThread();
if(th != null) { th putTasks(tasks); th startTasks();
}
}
public void processTasksInSingleThread(Collection tasks) {
PooledThread th = getIdleThread();
if(th != null) { th putTasks(tasks); th startTasks();
}
}
}
下面是線程池的測試程序
//ThreadPoolTest java
import java io BufferedReader; import java io IOException; import java io InputStreamReader;
import polarman threadpool ThreadPool; import polarman threadpool ThreadTask;
public class ThreadPoolTest {
public static void main(String[] args) { System out println( quit 退出 ); System out println( task A 啟動任務A 時長為 秒 ); System out println( size 設置當前線程池大小為 ); System out println( max 設置線程池最大線程數為 ); System out println();
final ThreadPool pool = new ThreadPool( ); pool init();
Thread cmdThread = new Thread() { public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(System in));
while(true) { try { String line = reader readLine(); String words[] = line split( ); if(words[ ] equalsIgnoreCase( quit )) { System exit( ); }else if(words[ ] equalsIgnoreCase( size ) && words length >= ) { try { int size = Integer parseInt(words[ ]); pool setPoolSize(size); }catch(Exception e) {
}
}else if(words[ ] equalsIgnoreCase( max ) && words length >= ) { try { int max = Integer parseInt(words[ ]); pool setMaxPoolSize(max); }catch(Exception e) {
}
}else if(words[ ] equalsIgnoreCase( task ) && words length >= ) { try { int timelen = Integer parseInt(words[ ]); SimpleTask task = new SimpleTask(words[ ] timelen * ); pool processTask(task); }catch(Exception e) {
}
}
} catch (IOException e) { e printStackTrace();
}
}
}
};
cmdThread start();
/**//*
for(int i= ; i< ; i++){
SimpleTask task = new SimpleTask( Task + i (i+ )* ); pool processTask(task);
}*/
}
}
class SimpleTask implements ThreadTask {
private String taskName;
private int timeLen;
public SimpleTask(String taskName int timeLen) { this taskName = taskName; this timeLen = timeLen;
}
public void run() { System out println(Thread currentThread() getId() +
: START TASK + taskName + );
try { Thread sleep(timeLen); } catch (InterruptedException e) {
}
System out println(Thread currentThread() getId() +
: END TASK + taskName + );
}
}
使用此線程池相當簡單 下面兩行代碼初始化線程池
ThreadPool pool = new ThreadPool( ); pool init();
要處理的任務實現ThreadTask 介面即可(如測試代碼里的SimpleTask) 這個介面只有一個方法run()
兩行代碼即可調用
lishixin/Article/program/Java/hx/201311/27203