#import "ViewController.h"
int threadNumber = 0;
int newThingNumber = 0;
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
//1如果主线程和子线程是并行的,倚靠CPU的调度,主线程和子线程都有机会得到执行。
//2如果要在子线程里面改变主线程里面的数据,就在里面的最后 一个参数使用传地调用(void *)&c,否则使用传值调用(void *)c
//3使用pthread_join的目的在于:怕主线程执行的过快,子线程还没有执行,主线程就执行完毕并且退出了。
- (IBAction)doSomething:(id)sender {
// 如果是在单线程里执行,则按纽状态的执行中字样会一直持续10秒
// 目前,对于iOS来说, 程序的GUI,是在主线程里执行的。换句话:所有UI程序都应该在主线程里运行
// 默认情况, button的回调方法, 是在主线程运行着
// [self doThing:nil];
// 开启新的线程,意思是同步执行(同步)
// 第一种办法来开启一个新的线程
// 第一个参数:开启后台线程, 需要执行的代码(任务), 第二个参数是线程通信参数
// [self performSelectorInBackground:@selector(doThing:) withObject:@"Hellowangdelong"];
// 第二种开启线程的方法
// 启动一个子线程,并使用doThing:作为线程的入口点(线程任务)
// 第二个参数:指定是哪个对象定义了线程的入口点(线程作务),
// 第三个参数:传递给子线程的数据(实现线程这间通信的手段)
// [NSThread detachNewThreadSelector:@selector(doThing:) toTarget:self withObject:@"Hello"];
// 第三种开启线程的方法
// 创建一个线程对象, 可以实现对线程何时开始运行的控制。
// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(doThing:) object:@"qingYun"];
// 给线程起一个名字, 用来标识这个线程。
// thread.name = @"FirstQingYunThread";
// 启动线程
// [thread start];
// 第四种开启线程的方法
// 创建一个队列
// NSOperationQueue *queque = [[NSOperationQueue alloc] init];
// 创建子任务, 定义子任务必须是NSOperation的子类
// NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doThing:) object:@"HelloOperationQueue"];
// 当把任务添加到队列后, 自动开启线程,
// [queque addOperation:operation];
// 在同一个NSOperationQueue队列不同出现同一个任务对象,否则会出现异常
// [queque addOperation:operation];
// 第五种开启线程的方法
// NSOperationQueue *queque = [[NSOperationQueue alloc] init];
// NSBlockOperation *oper = [NSBlockOperation blockOperationWithBlock:^{
// NSLog(@"do thing...");
// threadNumber++;
// // 表示当前执行doThing的线程对象
// NSThread *currentThread = [NSThread currentThread];
//
// // isMainThread:如果是主线程的话, 则返回YES,否则NO
// if ([currentThread isMainThread]) {
// NSLog(@"Main thread...%d",threadNumber);
// }else
// {
// NSLog(@"Peer thread...%d",threadNumber);
// }
//
// [NSThread sleepForTimeInterval:10];//让处理器休眠10秒
// NSLog(@"finish doThing");
//
// }];
//
// [queque addOperation:oper];
//
// 第六种开启线程的方法
// GCD
// Serial 队列 (NULL, nil Nil NSNull)的区别是什么?第一个参数是唯一标识创建的队列对象的
#if 0
dispatch_queue_t queue = dispatch_queue_create("wangdelong", NULL);
// 异步执行GCD的block(线程任务)
// 1、对于serial队列来说,主线程可以理解为一个queue, queue 与queue之间肯定异步执行,
// 2、对于同一个serial队列时的子任务,同步执行,遵循FIFO
dispatch_async(queue, ^{
NSLog(@"doThing...");
threadNumber++;
// 表示当前执行doThing的线程对象
NSThread *currentThread = [NSThread currentThread];
//如果是在主线程里执行的话, 打印出在主线程。
// 否则,则打印是对等线程
// 判断是主线程还是对等线程(异步)
if ([currentThread isMainThread]) {
NSLog(@"Main thread is :%d",threadNumber);
}else{
NSLog(@"Peer thread id :%d",threadNumber);
}
// //让处理器休眠10秒
[NSThread sleepForTimeInterval:5];
NSLog(@"finish working");
});
// dispatch_queue_t secondqueue = dispatch_queue_create("wangdelong", NULL);
dispatch_async(queue, ^{
NSLog(@" doThing...");
threadNumber++;
// 表示当前执行doThing的线程对象
NSThread *currentThread = [NSThread currentThread];
//如果是在主线程里执行的话, 打印出在主线程。
// 否则,则打印是对等线程
// 判断是主线程还是对等线程(异步)
if ([currentThread isMainThread]) {
NSLog(@"secondMain thread is :%d",threadNumber);
}else{
NSLog(@"secondPeer thread id :%d",threadNumber);
}
// //让处理器休眠10秒
[NSThread sleepForTimeInterval:5];
NSLog(@"second finish working");
});
#endif
// Concurrent 队列 同一个队列里的多个子任务之间也是并发执行的(注意这是与serial队列的区别)
// 同一个队列的不同子任务并发执行
// 不同的队列,他的调度顺序是根据优先级来确定, 优先级高的, 先调度。
// 第一个参数:用于标识队列的优先级,有如下几种:
// #define DISPATCH_QUEUE_PRIORITY_HIGH
// #define DISPATCH_QUEUE_PRIORITY_DEFAULT
// #define DISPATCH_QUEUE_PRIORITY_LOW
// #define DISPATCH_QUEUE_PRIORITY_BACKGROUND
// 第二个参数:写0就可以, 目前保留
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t secondqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
NSLog(@"first doThing...");
threadNumber++;
// 表示当前执行doThing的线程对象
NSThread *currentThread = [NSThread currentThread];
//如果是在主线程里执行的话, 打印出在主线程。
// 否则,则打印是对等线程
// 判断是主线程还是对等线程(异步)
if ([currentThread isMainThread]) {
NSLog(@"first Main thread is :%d",threadNumber);
}else{
NSLog(@"first Peer thread id :%d",threadNumber);
}
// //让处理器休眠10秒
[NSThread sleepForTimeInterval:5];
NSLog(@"first finish working");
});
dispatch_sync(secondqueue, ^{
NSLog(@"second doThing...");
threadNumber++;
// 表示当前执行doThing的线程对象
NSThread *currentThread = [NSThread currentThread];
//如果是在主线程里执行的话, 打印出在主线程。
// 否则,则打印是对等线程
// 判断是主线程还是对等线程(异步)
if ([currentThread isMainThread]) {
NSLog(@"second Main thread is :%d",threadNumber);
}else{
NSLog(@"second Peer thread id :%d",threadNumber);
}
// //让处理器休眠10秒
[NSThread sleepForTimeInterval:5];
NSLog(@"second finish working");
});
// 表示当前执行doThing的线程对象
NSThread *currentThread = [NSThread currentThread];
// isMainThread:如果是主线程的话, 则返回YES,否则NO
if ([currentThread isMainThread]) {
NSLog(@"This is Main thread...%d",threadNumber);
}else
{
NSLog(@"This is Peer thread...%d",threadNumber);
}
}
-(void)doThing:(id)object
{
NSLog(@"doThing...:%@",object);
threadNumber++;
// 表示当前执行doThing的线程对象
NSThread *currentThread = [NSThread currentThread];
//如果是在主线程里执行的话, 打印出在主线程。
// 否则,则打印是对等线程
// 判断是主线程还是对等线程(异步)
if ([currentThread isMainThread]) {
NSLog(@"Main thread is :%d",threadNumber);
}else{
NSLog(@"Peer thread id :%d",threadNumber);
}
// //让处理器休眠10秒
[NSThread sleepForTimeInterval:10];
NSLog(@"finish working");
}
//重新定义一个button,
- (IBAction)doNewThing:(id)sender {
NSLog(@"do another thing...:%d",newThingNumber);
newThingNumber++;
if ([NSThread isMainThread]) {
NSLog(@"do another thing is main thread");
}else
{
NSLog(@"do another thing is peer thread");
}
[NSThread sleepForTimeInterval:3];
NSLog(@"do another thing finished");
}
@end