引言
在涉及多線程并發(fā)操作時(shí),如何管理多線程對共享數(shù)據(jù)的訪問以及防止線程間的死鎖問題是個(gè)很重要的話題。在 Java 語言中,從 Java 5 開始, Java 提供了自己的線程池 ThreadPoolExecutor 類;在 iPhone 中則提供了 NSOperationQueue 類進(jìn)行多線程的管理和調(diào)度。
什么是線程池?
線程池到底是怎么一回事呢?其實(shí)線程池的原理很簡單,類似于操作系統(tǒng)中的緩沖區(qū)的概念,它的典型的執(zhí)行流程如下:
首先,啟動(dòng)若干數(shù)量的線程,并讓這些線程處于睡眠狀態(tài)
其次,當(dāng)客戶端有新的請求時(shí),線程池會喚醒某一個(gè)睡眠線程,讓它來處理客戶端的請求
最后,當(dāng)請求處理完畢,線程又處于睡眠狀態(tài)
Java 線程池
線程池可以由程序員自己來實(shí)現(xiàn),但是從 Java 5 開始, Java 語言自帶了線程池的類 ThreadPoolExecutor ,這個(gè)類提供了典型的線程池管理的接口,來研究 ThreadPoolExecutor 類的實(shí)現(xiàn)無疑更有借鑒意義。
ThreadPoolExcutor 類常用的構(gòu)造方式為
ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue《Runnable》 workQueue,RejectedExecutionHandler handler)
參數(shù) corePoolSize 為線程池維護(hù)線程的最少數(shù)量
參數(shù) maximumPoolSize 為線程池維護(hù)線程的最大數(shù)量
參數(shù) keepAliveTime 為線程池維護(hù)線程所允許的空閑時(shí)間
參數(shù) unit 為線程池維護(hù)線程所允許的空閑時(shí)間的單位
參數(shù) workQueue 為線程池所使用的緩沖隊(duì)列
參數(shù) handler 為線程池對拒絕任務(wù)的處理句柄
一個(gè)任務(wù)可以通過 excute(Runnable) 方法被添加到線程池,任務(wù)就是一個(gè)實(shí)現(xiàn)了 Runnable 接口的對象,而線程池通過 Runnable 類型對象的 run() 方法來執(zhí)行任務(wù)。
典型的用法如下:
首先,構(gòu)造一個(gè)線程池
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(2,4,3,TimeUnit.SECONDS,new ArrayBlockingQueue《Runnable》(3),new ThreadPoolExecutor.DiscardOldestPolicy());
for(int i = 1;i 《= 5;i++)
{
try
{
String task = “task@”+i;
System.out.println(“put”+task);
threadPool.execute(new ThreadPoolTask());
}
}
catch(Exception e)
{
e.printStackTrace();
}
而線程池所要執(zhí)行的任務(wù)對象需要實(shí)現(xiàn) Runnable 接口,線程池執(zhí)行任務(wù)對象時(shí)調(diào)用任務(wù)對象的 run() 方法,它的實(shí)現(xiàn)代碼如下:
public class ThreadPoolTask implements Runnable{
ThreadPoolTask(){}
public void run(){
System.out.println(“start execute”);
}
}
iPhone 操作隊(duì)列
iPhone 本身也支持多線程開發(fā),同樣, NSThread 類提供對多線程開發(fā)的支持時(shí)也面臨多線程的共享數(shù)據(jù)管理和死鎖問題,于是 iPhone 也提供了類似于 Java 線程池的解決方案:任務(wù)隊(duì)列 NSOperationQueue 類。
和 Java 語言的 Runnable 接口一樣, iPhone 提供了 NSOperation 接口進(jìn)行任務(wù)對象的封裝,而通過將任務(wù)對象加入到 NSOperationQueue 隊(duì)列, NSOperationQueue 隊(duì)列會分配線程進(jìn)行任務(wù)對象的執(zhí)行,任務(wù)對象的執(zhí)行通過 - (void)main 方法,下面是典型的任務(wù)對象和任務(wù)隊(duì)列的實(shí)現(xiàn):
@interface ThreadPoolTask:NSOperation
{
}
@end
@implementation ThreadPoolTask
- (void)main
{
NSLog(@”start execute”);
}
@end
和 Java 語言中一樣,構(gòu)造一個(gè)多線程池并添加任務(wù)對象到線程池中,線程池會調(diào)用任務(wù)對象的 - (void)main 方法執(zhí)行任務(wù), iPhone 中典型的任務(wù)隊(duì)列的實(shí)現(xiàn)如下:
NSOperationQueue* threadPool = [[NSOperation alloc] init];
?。踭hreadPool setMaxConcurrentOperationCount:4];
for(int i = 1;i 《= 5;i++)
{
NSString* task = [NSString stringWithFormat:@”task %d”,i];
NSLog(@“put %@”,task);
[threadPool add:([[ThreadPoolTask alloc] init])];
}
可以看到, iPhone 通過 NSOperationQueue 提供了一套類似于線程池的機(jī)制,通過它可以更加方便的進(jìn)行多線程的并發(fā)操作,從而使得程序員從繁雜的多線程共享數(shù)據(jù)管理和死鎖問題中解脫出來。
(審核編輯: 智匯小新)
分享