1.三种方式:
NShread,GCD(Grand Central Dispatch),NSOperation&NSOperationQueue
2.创建/开启线程:
NSSTread:
// 创建
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];
// 启动
[thread start];
或者创建并启动:
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];
然后
[self performSelectorInBackground:@selector(run:) withObject:nil];
GCD:
dispatch_async(<#queue#>, ^{
//code here
NSLog(@"%@", [NSThread currentThread]);
});
这里queue,一般业务我们会返回主线程。dispatch_get_main_queue
4.线程间通信
我们在子线程请求完数据后回到主线程刷新tableView,就是很明显的线程间的通信实例。
1个线程传递数据给另1个线程
在1个线程中执行完特定任务后,转到另1个线程继续执行任务
线程间通信常用方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
GCD方式:
dispatch_async(dispatch_get_main_queue, ^{
//code here
NSLog(@"%@", [NSThread currentThread]);
});
5.线程安全(锁的问题即互斥锁)
为了防止多个线程操作一个数据资源造成线程安全问题
加锁方法:
1).
@synchronized(self)
{
此段代码对其他@synchronized(self)也是互斥的
}
2).
1.lock——加锁
2.unLock——解锁
6.队列
串行队列中的任务,里面的任务会按顺序执行,如果创建的是异步任务则新开辟一个线程去顺序的执行这些任务,如果创建的是同步任务则不开辟线程直接顺序执行这些任务。
并行队列中的任务,里面的任务如果是同步的则按顺序执行,且不开辟子线程,如果是异步的则每一个异步任务都会创建一个子线程,并且这些异步任务的执行顺序无法控制。
串行+异步:
创建子线程,因为是异步任务。
顺序执行,异步任务都放在那一个子线程中顺序执行,因为是串行。
并行+异步:
创建子线程,每一个异步任务都会创建一个子线程,因为异步任务。
非顺序执行,因为并行队列。
所以串行队列中添加异步任务使我们最常用的方式。
主队列中的任务都是在主线程完成的,所以下边虽然是异步,但不会开辟子线程:
dispatch_async(dispatch_get_main_queue, ^{
NSLog(@"come here");
});
但是你不能在主队列中添加同步任务,如下面会卡死:
dispatch_sync(q, ^{
NSLog(@"come here");
});