-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathThreadPool.m
More file actions
132 lines (116 loc) · 3.44 KB
/
ThreadPool.m
File metadata and controls
132 lines (116 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//
// ThreadPool.m
// ThreadPool
//
// Created by Kelp on 12/7/22.
// Copyright (c) 2012 Phate. All rights reserved.
//
#import "ThreadPool.h"
#pragma mark - ThreadPool
@implementation ThreadPool
#pragma mark - Property
@synthesize maxThreadNumber = _maxThreadNumber;
@synthesize delegate = _delegate;
- (BOOL)isPoolCleared
{
return [_poolExecute count] + [_poolQueue count] == 0;
}
static ThreadPool *instance;
#pragma mark - Initialize
+ (id)sharedInstance
{
@synchronized (instance) {
if (instance == nil) {
instance = [ThreadPool new];
}
return instance;
}
}
- (id)init
{
self = [super init];
if (self) {
_poolQueue = [NSMutableArray new];
_poolExecute = [NSMutableArray new];
_maxThreadNumber = 1;
}
return self;
}
#pragma mark push a thread
- (void)pushThread:(NSThread *)thread
{
[self pushThread:thread threadPoolType:ThreadPoolQueue];
}
- (void)pushThread:(NSThread *)thread threadPoolType:(ThreadPoolType)threadPoolType
{
switch (threadPoolType) {
case ThreadPoolCancelThis:
// cancel the new thread
if ([_poolExecute count] == 0 && [_poolQueue count] == 0) {
[_poolQueue addObject:thread];
}
break;
case ThreadPoolCancelBefore:
// cancel threads in pool and run the new thread
[_poolQueue removeAllObjects];
[self cancelAllthreadsInExecutePool];
[_poolQueue addObject:thread];
break;
case ThreadPoolQueue:
default:
[_poolQueue addObject:thread];
break;
}
if (_timer == nil) {
_timer = [[NSTimer alloc] initWithFireDate:[NSDate date]
interval:1
target:self
selector:@selector(checkThread:)
userInfo:nil
repeats:true];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
}
}
#pragma mark thread managementor
- (void)checkThread:(NSTimer *)timer
{
// check execute pool
NSMutableIndexSet *indexSet = [NSMutableIndexSet new];
for (int index = 0; index < [_poolExecute count]; index++) {
NSThread *thread = [_poolExecute objectAtIndex:index];
if (thread.isFinished) {
[indexSet addIndex:index];
}
}
[_poolExecute removeObjectsAtIndexes:indexSet];
// execute a new thread
while ([_poolExecute count] < _maxThreadNumber && [_poolQueue count] > 0) {
NSThread *thread = [_poolQueue objectAtIndex:0];
[_poolExecute addObject:thread];
[_poolQueue removeObjectAtIndex:0];
[thread start];
}
// turn off timer
if ([_poolQueue count] + [_poolExecute count] == 0) {
[_timer invalidate];
_timer = nil;
if (_delegate) {
[(NSObject *)_delegate performSelectorOnMainThread:@selector(poolCleared:)
withObject:self
waitUntilDone:false];
}
}
}
#pragma mark cancel thread
- (void)cancelAllthreadsInExecutePool
{
for (NSThread *thread in _poolExecute) {
[thread cancel];
}
}
- (void)cancelAllThreads
{
[_poolQueue removeAllObjects];
[self cancelAllthreadsInExecutePool];
}
@end