結(jié)論:setMaxConcurrentOperationCount 不能控制線程池中的線程數(shù)或線程數(shù)上限(或者說不是唯一因素)
摘自官方文檔對 setMaxConcurrentOperationCoun 的說明 : affects only the operations that the current queue has executing at the same time. 翻譯過來,就是影響同時執(zhí)行的 operations 數(shù),此處的 operations 是一個任務(wù)單位,使用者將子任務(wù)以 NSOperation 對象的形式添加。
這里的 NSOperation 可以理解成一個任務(wù),但不能理解成這個任務(wù)只對應(yīng)一個處理線程。
如: NSBlockOperation對象 是NSOperation類的一個子類, NSBlockOperation類有
+ (instancetype)blockOperationWithBlock:(void (^)(void))block;
初始化方法, 此方法可以以block的形式添加一個子任務(wù), 另外他還有
- (void)addExecutionBlock:(void (^)(void))block;
的對象方法, 用來繼續(xù)添加block形式的子任務(wù).
而使用了NSBlockOperation對象作為任務(wù) 添加到 NSOperationQueue時, 每個任務(wù)則可能不止對應(yīng)一個線程.
實例代碼如:
NSMutableDictionary *dicMuThreads = [NSMutableDictionary dictionary];
NSLock *lock = [[NSLock alloc] init];
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"a" forKey:strThread];
NSLog(@"a--%@",strThread);
[lock unlock];
}];
[op1 addExecutionBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"a" forKey:strThread];
NSLog(@"a--%@",strThread);
[lock unlock];
}];
[op1 addExecutionBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"a" forKey:strThread];
NSLog(@"a--%@",strThread);
[lock unlock];
}];
//注釋1
// [op1 addExecutionBlock:^{
// [lock lock];
// NSThread *current = [NSThread currentThread];
// NSString *strThread = [NSString stringWithFormat: @"%@",current];
// [dicMuThreads setObject:@"a" forKey:strThread];
// NSLog(@"a--%@",strThread);
// [lock unlock];
// }];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"b" forKey:strThread];
NSLog(@"b--%@",strThread);
[lock unlock];
}];
[op2 addExecutionBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"b" forKey:strThread];
NSLog(@"b--%@",strThread);
[lock unlock];
}];
//注釋2
// [op2 addExecutionBlock:^{
// [lock lock];
// NSThread *current = [NSThread currentThread];
// NSString *strThread = [NSString stringWithFormat: @"%@",current];
// [dicMuThreads setObject:@"b" forKey:strThread];
// NSLog(@"b--%@",strThread);
// [lock unlock];
// }];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"c" forKey:strThread];
NSLog(@"c--%@",strThread);
[lock unlock];
}];
[op3 addExecutionBlock:^{
[lock lock];
NSThread *current = [NSThread currentThread];
NSString *strThread = [NSString stringWithFormat: @"%@",current];
[dicMuThreads setObject:@"c" forKey:strThread];
NSLog(@"c--%@",strThread);
[lock unlock];
}];
//注釋3
// [op3 addExecutionBlock:^{
// [lock lock];
// NSThread *current = [NSThread currentThread];
// NSString *strThread = [NSString stringWithFormat: @"%@",current];
// [dicMuThreads setObject:@"c" forKey:strThread];
// NSLog(@"c--%@",strThread);
// [lock unlock];
// }];
NSOperationQueue *opeQueue = [[NSOperationQueue alloc]init];
[opeQueue setMaxConcurrentOperationCount:2];
[opeQueue addOperation:op1];
[opeQueue addOperation:op2];
[opeQueue addOperation:op3];
[opeQueue setSuspended: NO];
[opeQueue waitUntilAllOperationsAreFinished];
NSLog(@"線程總數(shù)是:%ld",dicMuThreads.count);
有注釋1 注釋2 注釋3, 三處注釋時結(jié)果如下

只取消注釋2 時 結(jié)果如下:

只取消注釋 1和 2時, 結(jié)果如下:

總結(jié)實驗結(jié)果,規(guī)律比較清晰:setMaxConcurrentOperationCount 和當(dāng)前 operation 的子任務(wù)數(shù) (NSBlockOperation) 結(jié)合起來影響線程數(shù) : maxConcurrentOperationCount 屬性值為 2 時,則要開辟的線程數(shù)是,所有子任務(wù)中 NSBlockOperation 個數(shù)最多的 2 個子任務(wù)的 NSBlockOperation 個數(shù)之和;這樣設(shè)計的原因也變的很合理。