當前位置:首頁 » 編程語言 » java線程實例

java線程實例

發布時間: 2024-10-09 00:05:34

java澶氱嚎紼嬪垵瀛﹁呮寚鍗楋紙3錛夛細浣跨敤Runnable鎺ュ彛鍒涘緩綰跨▼

銆銆涓婁竴綃 Java澶氱嚎紼嬪垵瀛﹁呮寚鍗楋紙 錛 鐢═hread綾誨壋寤虹嚎紼

銆銆瀹炵幇Runnable鎺ュ彛鐨勭被蹇呴』浣跨敤Thread綾葷殑瀹炰緥鎵嶈兘鍒涘緩綰跨▼ 閫氳繃Runnable鎺ュ彛鍒涘緩綰跨▼鍒嗕負涓ゆ

銆銆 灝嗗疄鐜癛unnable鎺ュ彛鐨勭被瀹炰緥鍖

銆銆 寤虹珛涓涓猅hread瀵硅薄 騫跺皢絎涓姝ュ疄渚嬪寲鍚庣殑瀵硅薄浣滀負鍙傛暟浼犲叆Thread綾葷殑鏋勯犳柟娉

銆銆鏈鍚庨氳繃Thread綾葷殑start鏂規硶寤虹珛綰跨▼

銆銆涓嬮潰鐨勪唬鐮佹紨紺轟簡濡備綍浣跨敤Runnable鎺ュ彛鏉ュ壋寤虹嚎紼

銆銆 packagemythread;{publicvoidrun(){System out println(Thread currentThread() getName());}publicstaticvoidmain(String[]args){MyRunnablet =newMyRunnable();MyRunnablet =newMyRunnable();Threadthread =newThread(t MyThread );Threadthread =newThread(t );thread setName( MyThread );thread start();thread start();}}

銆銆涓婇潰浠g爜鐨勮繍琛岀粨鏋滃備笅

lishixin/Article/program/Java/gj/201311/27466

❷ 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多線程之ThreadPoolExecutor原理(圖文代碼實例詳解)

ThreadPoolExecutor是Java的線程池並發代名詞,多線程開發基本都是基於這個去做具體的業務開發。雖然覺得自己回了,網上帖子已經有很多的文章寫這個,但是是自己一一點寫的,終歸是要比看別人的理解更加深刻,所以最近自己在對java知識的系統梳理。那麼接下來主要分析下這個多線程框架的原理。

ThreadPoolExecutor的構造函數以成員變數介紹publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueue<Runnable>workQueue,ThreadFactorythreadFactory,){

面試靠的最多是這個構造函數中7個參數的作用,

corePoolSize是核心線程數,即使線程是空閑的,線程池一直保持的的線程數,除非allowCoreThreadTimeOut參數設置為true

maximumPoolSize線程池最大線程數

keepAliveTimeunit線程存活時間和時間單位

workQueue是任務隊列,是用來保持task,該隊列保持住了Runnable的任務,通過調用線程池的execute的方法.

threadFactory創建線程的工廠

RejectedExecutionHandler是當線程數超過限制以及隊列也滿了,需要執行的拒絕策略.

成員變零

privatefinalAtomicIntegerctl=newAtomicInteger(ctlOf(RUNNING,0));privatestaticfinalintCOUNT_BITS=Integer.SIZE-3;privatestaticfinalintCAPACITY=(1<<COUNT_BITS)-1;//線程容量//runStateisstoredinthehigh-=-1<<COUNT_BITS;privatestaticfinalintSHUTDOWN=0<<COUNT_BITS;privatestaticfinalintSTOP=1<<COUNT_BITS;privatestaticfinalintTIDYING=2<<COUNT_BITS;=3<<COUNT_BITS;

面試最喜歡問的是ctl變數的代表什麼意義?ctl變數的的的用高3位表示線程池的狀態,用低29位表示線程個數,兩者通過|操作,拼接出ctl變數,也就是線程池的最大線程數capacity是(2^29)-1。

線程池狀態

RUNNING運行狀態-1<<29表示線程池可以接新的任務並且處理隊列任務

SHUTDOWN關閉狀態態-1<<29表示線程池不接受新的線程池任務但是可以處理隊列中的任務

STOP停止狀態1<<29表示線程池不接受新的線程池任務也不處理隊列中的任務並且中斷線程池裡中正在執行的任務

TIDYING2<<29表示所有的線程池都已經中斷了,線程數為0,線程狀態轉為為TIDYING,將執行terminated鉤子函數

TERMINATED3<<29表示所有terminated方法都已經執行完成。

線程狀態之間裝換圖

線程池的提交任務執行流程

首先我們來看平時業務代碼是提交任務到線程池執行的函數是通過execute或者submit方法,區別就是submit返回具有Future,execute返回void,的、那麼接下來我們主要分析execute的執行流程,submit涉及到線程非同步返回,之後會另外單獨分析,那麼下面這個execute函數就能看出線程池的整個執行流程,

publicvoidexecute(Runnablecommand){if(command==null)thrownewNullPointerException();/**Proceedin3steps:**1.,tryto**task.*workerCount,*threadswhenitshouldn't,byreturningfalse.**2.,thenwestillneed*todouble-*()orthat*.Sowe**stopped,.**3.Ifwecannotqueuetask,thenwetrytoaddanew*thread.Ifitfails,*andsorejectthetask.*/intc=ctl.get();if(workerCountOf(c)<corePoolSize){if(addWorker(command,true))return;c=ctl.get();}if(isRunning(c)&&workQueue.offer(command)){intrecheck=ctl.get();if(!isRunning(recheck)&&remove(command))reject(command);elseif(workerCountOf(recheck)==0)//當線程池的核心線程數設置為0情況下,那麼這時workerCountOf(recheck)為0,這時就開啟非線程數處理隊列任務addWorker(null,false);}elseif(!addWorker(command,false))reject(command);}

線程池執行任務流程圖如下:

我相信大概的流程一般同學是清楚的:

當線程數的Worker線程<corePoolSize創建核心線程數執行

當線程數的Worker線程>corePoolSize,將任務加入任務隊列中

則當corePoolSize<maxPoolsize,則新增非核心線程執行任務

當隊列滿了,線程數也已經達到maxPoolsize,則執行拒絕策略

實際源碼中執行流程還有一些小細節容易被忽略的地點

重新檢查線程的狀態以及檢查線程池的線程數的流程

線程池新增工作線程的流程

線程池新增工作任務主要addWorker方法。由於代碼比較長,我就在代碼里寫好注釋

privatebooleanaddWorker(RunnablefirstTask,booleancore){retry:for(;;){intc=ctl.get();intrs=runStateOf(c);//.if(rs>=SHUTDOWN&&//第一個條件:線程至少不是運行狀態,那麼就是shutdownstoptidying,terminated狀態!(rs==SHUTDOWN&&firstTask==null&&!workQueue.isEmpty()))//第二個條件:當前線程池是shutdown狀態且任務隊列非空並且工作任務第一個任務是空的取反條件,這個含義是當除了SHUTDOWN狀態且第一個任務為空且任務隊列不為空//情況下,直接返回false,增加Work線程失敗returnfalse;for(;;){intwc=workerCountOf(c);if(wc>=CAPACITY||wc>=(core?corePoolSize:maximumPoolSize))returnfalse;if((c))breakretry;c=ctl.get();//Re-readctlif(runStateOf(c)!=rs)continueretry;//;retryinnerloop}}booleanworkerStarted=false;booleanworkerAdded=false;Workerw=null;try{w=newWorker(firstTask);finalThreadt=w.thread;if(t!=null){finalReentrantLockmainLock=this.mainLock;mainLock.lock();try{//Recheckwhileholdinglock.////shutdownbeforelockacquired.intrs=runStateOf(ctl.get());if(rs<SHUTDOWN||//線程池是running狀態(rs==SHUTDOWN&&firstTask==null)){//線程池處於shutdown狀態並且第一個task為空if(t.isAlive())//();//加入工作線程的集合workers.add(w);ints=workers.size();if(s>largestPoolSize)//記錄最大線程數largestPoolSize=s;workerAdded=true;}}finally{-mainLock.unlock();-}-if(workerAdded){-t.start();workerStarted=true;}}}finally{if(!workerStarted)addWorkerFailed(w);}returnworkerStarted;}

添加工作線程主要步驟

檢查線程池的運行狀態以及隊列是否是空,增加線程。為什麼增加這個判斷,主要是因為線程池是多線程的隨便可能另外調用shutdown等方法關閉線程池,所以做每一步之前都要再次check線程池的狀態,其中比較重要的點是線程池在除了Running狀態,其他的只有shutdow狀態,且隊列任務非空的情況,才能增加work線程處理任務。

判斷線程池的線程是核心線程數,然後就判斷大於核心線程數,如果不是增加的核心線程數,然後通過CAS增加線程數加1,然後re-read的ctl的現在的狀態是否剛開始進入循環的狀態保持一致。

創建Worker對象,它的第一個參數Runable就是執行的第一個task,然後獲取mainLock的重入鎖,然後再次判斷線程池的狀態是否是shutdown狀態,然後將Worker對象加入工作線程的Set集合中,判斷是大於largePoolSize,則將workSet的size賦值largePoolSize,然後賦值workerAdded為true,接下來在finnally中workerAdded為true,則調用Worker的start方法啟動該Worker線程,

如果WorkerAdded失敗,則從Worder的Set移除剛才加入Worker線程,並將線程池的線程數減1,

工作線程Worker的執行流程

首先來看下Work的類的成員變數的構造函數,從下面的Work的代碼,可以看到它是實現了RUnnable介面,上一節Worker啟動是調用了它的start方法,真正由操作系統調度執行的其run方法,那麼接下來重點看下run的工作流程。

able{/***,butweprovidea*.*/=6138294804551838833L;/**Threadthisworkerisrunningin.Nulliffactoryfails.*/finalThreadthread;/**Initialtasktorun.Possiblynull.*/RunnablefirstTask;/**Per-threadtaskcounter*/volatilelongcompletedTasks;/***.*@paramfirstTaskthefirsttask(nullifnone)*/Worker(RunnablefirstTask){//初始化狀態為-1,表示不能被中斷setState(-1);//.firstTask=firstTask;this.thread=getThreadFactory().newThread(this);}

下面代碼中Work的run直接調用runWork,並傳入自身對象,開始一個循環判斷第一個任務後者從任務隊列中取任務不為空,就開始上鎖,然後執行任務,如果任務隊列為空了,則處理Work的退出。

/***/publicvoidrun(){//直接調用runWorker函數runWorker(this);}finalvoidrunWorker(Workerw){//Wokder當前線程Threadwt=Thread.currentThread();Runnabletask=w.firstTask;w.firstTask=null;//將state值賦值為0,這樣就運行中斷w.unlock();//=true;try{//循環判斷第一個Task獲取從獲取任務while(task!=null||(task=getTask())!=null){//獲取當前Work的鎖,處理任務,也就是當前Work線程處理是同步處理任務的w.lock();//Ifpoolisstopping,ensurethreadisinterrupted;//ifnot,ensurethreadisnotinterrupted.This//////線程池的狀態至少是stop,即使stop,tidying.terminated狀態if((runStateAtLeast(ctl.get(),STOP)//檢查線程是否中斷且清楚中斷||(Thread.interrupted()&&//再次檢查線程池的狀態至少是STOPrunStateAtLeast(ctl.get(),STOP)))&&//再次判斷是否中斷!wt.isInterrupted())//中斷線程wt.interrupt();try{//執行業務任務前處理(鉤子函數)beforeExecute(wt,task);Throwablethrown=null;try{//這里就是執行提交線程池的Runnable的任務的run方法task.run();}catch(RuntimeExceptionx){thrown=x;throwx;}catch(Errorx){thrown=x;throwx;}catch(Throwablex){thrown=x;thrownewError(x);}finally{//執行業務任務後處理(鉤子函數)afterExecute(task,thrown);}}finally{//執行結束重置為空,回到while循環拿下一個task=null;//處理任務加1w.completedTasks++;//釋放鎖,處理下一個任務w.unlock();}}//代碼執行到這里,代表業務的任務沒有異常,不然不會走到這里,//因為上一層try沒有catch異常的,而業務執行出現異常,最里層//雖然catch了異常,但是也都通過throw向外拋出completedAbruptly=false;}finally{//如果循環結束,則處理Work退出工作,代表任務拿不到任務,即任務隊列沒有任務了processWorkerExit(w,completedAbruptly);}}

下面就來看下getTask獲取任務隊列的處理邏輯、如果這里返回null,即runWorker循環退出,則會處理finnaly中processWorkExit,處理Work線程的退出,下面是getWork返回null的情況:

如果線程池狀態值至少是SHUTDOWN狀態,並且線程池狀態值至少是STOP狀態,或者是任務隊列是空,則將線程池的workcout減1,並返回null,

計算線程池中線程池的數量,如果線程數量大於最大線程數量,或者allowCoreThreadTimeOut參數為true或者線程數大於並且任務隊列為空,則將線程池減1,並返回null,

privateRunnablegetTask(){//超時標志booleantimedOut=false;//Didthelastpoll()timeout?for(;;){//獲取線程狀態intc=ctl.get();//線程狀態intrs=runStateOf(c);//.//如果線程池狀態值至少是SHUTDOWN狀態,if(rs>=SHUTDOWN線程池狀態值至少是STOP狀態,或者是任務隊列是空&&(rs>=STOP||workQueue.isEmpty())){//CAS將worker線程數減1decrementWorkerCount();returnnull;}//計算線程池線程數量intwc=workerCountOf(c);//Areworkerssubjecttoculling?//allowCoreThreadTimeOut參數設置為true,或則線程池的線程數大於corePoolSize,表示需要超時的Worker需要退出,booleantimed=allowCoreThreadTimeOut||wc>corePoolSize;//線程數大於最大線程數||已經超時if((wc>maximumPoolSize||(timed&&timedOut))//線程數大於1或者任務隊列為空&&(wc>1||workQueue.isEmpty())){//CAS將線程數減1if((c))returnnull;continue;}try{//需要處理超時的Worker,則獲取任務隊列中任務等待的時間//就是線程池構造函數中keepAliveTime時間,如果不處理超時的Worker//則直接調用take一直阻塞等待任務隊列中有任務,拿到就返回Runnale任務Runnabler=timed?workQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS):workQueue.take();if(r!=null)returnr;timedOut=true;}catch(InterruptedExceptionretry){timedOut=false;}}}

Worker的退出處理:1從上面分析知道completedAbruptly是任務執行時是否出現異常標志,如果任務執行過程出錯,則將線程池的線程數量減12.加線程池的mainLock的全局鎖,這里主要區分Worker執行任務中,拿的是Worker內部的鎖,完成任務加1,將worker從Worker的集合移除,3.執行tryTerminate函數,是否線程池線程池是否關閉4.根據線程池狀態是否補充非核心的Worker線程去處理

privatevoidprocessWorkerExit(Workerw,booleancompletedAbruptly){//任務執行時出現異常,則減去工作if(completedAbruptly)//Ifabrupt,thenworkerCountwasn'tadjusteddecrementWorkerCount();//拿到線程池的主鎖finalReentrantLockmainLock=this.mainLock;//加鎖mainLock.lock();try{//完成任務加1completedTaskCount+=w.completedTasks;//將worker從Worker的集合移除workers.remove(w);}finally{mainLock.unlock();}//嘗試線程池關閉tryTerminate();//獲取線程池的ctlintc=ctl.get();//如果線程池的狀態值小於STOP,即使SHUTDOWNRUNNINGif(runStateLessThan(c,STOP)){//任務執行沒有異常if(!completedAbruptly){//allowCoreThreadTimeOut參數true,則min=0,表示不需要線程常駐。//負責是有corePoolSize個線程常駐線程池intmin=allowCoreThreadTimeOut?0:corePoolSize;if(min==0&&!workQueue.isEmpty())min=1;//如果線程池數大於最小,也就是不需要補充線程執行任務隊列的任務if(workerCountOf(c)>=min)return;//replacementnotneeded}//走到這里表示線程池的線程數為0,而任務隊列又不為空,得補充一個線程處理任務addWorker(null,false);}}

t

❹ 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

熱點內容
配置不高pr哪個版本最好用 發布:2024-10-09 01:57:15 瀏覽:787
編譯OpenWrtipv6 發布:2024-10-09 01:51:40 瀏覽:122
python寫入位元組 發布:2024-10-09 01:24:22 瀏覽:647
如何設置超高難度密碼 發布:2024-10-09 01:19:05 瀏覽:177
linux只讀文件修改 發布:2024-10-09 01:13:08 瀏覽:84
安卓機電腦用什麼檢測 發布:2024-10-09 01:10:20 瀏覽:671
有關資料庫的工作 發布:2024-10-09 00:52:12 瀏覽:734
代碼分析演算法 發布:2024-10-09 00:47:11 瀏覽:163
晶元寫程序需要配置哪些文件 發布:2024-10-09 00:38:39 瀏覽:936
存儲儲存搬運 發布:2024-10-09 00:28:42 瀏覽:718