iOS-多线程

2016-07-21  本文已影响5人  蓝蓝的白云

一、多线程的初步理解

二、多线程的分类及优缺点

1. pthread

优点:可以跨平台使用,基于纯C语言的面向对象,能够适用于多种操作系统, 可移植性强。
缺点:靠近底层实现,难以理解且使用难道大,线程的生命周期需要程序员自己管理,通常不使用。
举例:在view did load里面写如下代码 ( 注:需导入头文件 #import<pthread.h>)

  pthread_t  pthread;新建一个

// 第一个参数: 线程指针

// 第二个参数: 线程的一些属性

// 第三个参数: 函数指针, 用于执行方法

// 第四个参数: 线程中的传值

    pthread_create(&pthread, NULL, run, NULL);

方法实现 :

void *run(void *papa)

{

for (NSInteger i = 0; i < 100000; i ++) {

NSLog(@"%lu",i);

}

return NULL;

}

2.NSThread

NSTHread *thread =[ [NSThread alloc] initWithTarget:self selector:@selector(run) objects:"thread"];

thread.name = "thread"

[thread start] // 开启线程

NSLog(@"%@",thread);  // 线程打印 

NSLog(@"%@",[NSThread mainThread]);  // 当前应用程序的主线程

NSLog(@"%@",[NSThread currentThread]); // 当前线程

NSLog(@"%d",[NSThread isMainThread]); // 判断是否为主线程

// 快捷创建NSThread线程的方法

[NSThread detachNewThreadSelector:@selector(haoshicaozuo) toTarget:self withObject:@"123"];

[self performSelectorInBackground:@selector(haoshicaozuo) withObject:@"123"];

3.NSOperation

简介:NSOperation是个抽象类,我们一般不使用它,一般使用它的子类NSInvocationOperation和NSBlockOperation, 如果他们单独使用,则都是在主线程下执行,只有和队列放在一起才在子线程执行。

a.NSInvocationOperation

NSInvocationOperation *firstOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstRun) object:nil];

- (void) firstRun{

NSlog("第一个NSInvocation线程")

}



NSInvocationOperation *secondOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(secondRun) object:nil];

- (void) secondRun{

NSlog("第二个NSInvocation线程")

}

b.NSBlockOperation

NSBlockOperation  *thirdOperation  = [NSBlockOperation blockOperationWithBlock:^{

NSlog("block线程")

}

}];


//  NSOperationQueue *queue = [NSOperationQueue mainQueue]; mainQueue代表主队列

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // alloc init 代表其他队列

NSOperationQueue的作⽤:NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的,

如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation

中的操作

添加操作到NSOperationQueue中,自动执行操作,自动开启线程

// 先加的先执行, 后加的后执行, 但是执行的时间不一定, 可能后执行的程序比先执行的先执行完

[queue addOperation:firstOperation];  // 将线程加入队列

[queue addOperation:secondOperation]; // 将线程加入队列

[queue addOperation:thirdOperation]; // 将线程加入队列

4. GCD

a.同步 + 主队列 (不具备开启线程的能力, 在当前的线程完成任务)

- (void)creatScyncSerial

{

// 创建串行队列

dispatch_queue_t queue = dispatch_queue_create("aaa.com.queue", DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

NSLog(@"1------%@",[NSThread currentThread]);  

});   // dispatch_sync为同步

dispatch_sync(queue, ^{

NSLog(@"2------%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"3------%@",[NSThread currentThread]);

});

}

注:NSlog出现不输出情况,因为同步串行出现相互等待的情况,程序无法运行

b.异步 + 串行队列(能开启线程, 任务一个一个执行)

- (void)creatAsyncSerial

{

dispatch_queue_t queue = dispatch_queue_create("aaa.com.queue", DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{

NSLog(@"4--------%@",[NSThread currentThread]);

}); // dispatch_async 为异步

dispatch_async(queue, ^{

NSLog(@"5--------%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"6--------%@",[NSThread currentThread]);

});

}

c.同步 + 并发队列(不具备开启线程的能力, 无法并发)

- (void)creatSyncConcurrent

{

// 第一个参数: 队列的名字

// 第二个参数: 队列的类型

// 我们自己创建的并发队列

//    dispatch_queue_t queue = dispatch_queue_create("sb.2b.com", DISPATCH_QUEUE_CONCURRENT);

// 创建一个并发队列

// 获得全局的并发队列

// 第一个参数为一个优先级: 默认的就行

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_sync(queue, ^{

NSLog(@"1-------%@",[NSThread currentThread]);    });

dispatch_sync(queue, ^{

NSLog(@"2------%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"3-------%@",[NSThread currentThread]);

});

}

d.异步 + 并发队列 (使用频率较高,具备开启子线程的能力, 并发执行)

- (void)creatAsncConcurrent

{

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{

NSLog(@"1------%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"2------%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{ 

NSLog(@"3------%@",[NSThread currentThread]);

});

}

4.NSThreade的简单应用(saleTickets)

a.将线程和票数设置为属性

@property (nonatomic,strong)NSThread *firstThread; // A售票员

@property (nonatomic,strong)NSThread *secondThread; // B售票员

@property (nonatomic,strong)NSThread *thirdThread; // C售票员

@property (nonatomic,assign)NSInteger ticketCount; // 总票数

b.添加线程并开启

self.ticketCount = 100;  // 总票数 设为100

self.firstThread = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];

self.secondThread = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];

self.thirdThread = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];

触摸屏幕时开启子线程

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event

{

[self.firstThread start];

[self.secondThread start];

[self.thirdThread start];

}

卖票的方法

- (void)saleTicket

{

while (1) {  // 设置1为死循环,未触发break时会一直运行卖票

// 线程锁 线程锁是唯一的, 只能有一把, 通常我们可以写上self, 加线程锁是防止三个线程同一时间卖票,当有一个线程开始卖票时,其他线程无法进行卖票。

@synchronized (self) {

//            NSLog(@"%@",self);

// 先取出总票数

NSInteger count = self.ticketCount;

if (count > 0) {

self.ticketCount = count - 1;

[NSThread sleepForTimeInterval:0.1];  // 线程暂停休息

NSLog(@"%@, %lu",[NSThread currentThread], self.ticketCount);

}else{

NSLog(@"票卖完了");

break;

           }

      }

}

上一篇 下一篇

猜你喜欢

热点阅读