多线程之-NSThread

多线程之-NSThread

介绍NSThread之前先介绍一下pthread,仅供了解,一般在开发中用不到的

pthread(了解)

  • 类型:
    • C语言中类型的结尾通常 _t/Ref,而且不需要使用 *
/*
参数说明:
     1. pthread_t *restrict 线程代号的地址
     2. const pthread_attr_t *restrict 线程的属性
     3. 调用函数的指针
        - void *(*)(void *)
        - 返回值 (函数指针)(参数)
        - void * 和 OC 中的 id 是等价的
     4. void *restrict 传递给该函数的参数
返回值:
     如果是0,表示正确
     如果是非0,表示错误码
*/
NSString *str = @"lnj";
    pthread_t thid;
    int res = pthread_create(&thid, NULL, &demo, (__bridge void *)(str));
    if (res == 0) {
        NSLog(@"OK");
    } else {
        NSLog(@"error %d", res);
    }

NSThread

  • 一个NSThread对象就代表一条线程

创建线程的几种方式:

  1. alloc/init
    // 1.创建线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo:) object:@"lnj"];
    // 设置线程名称
    [thread setName:@"xmg"];
    // 设置线程的优先级
    // 优先级仅仅说明被CPU调用的可能性更大
    [thread setThreadPriority:1.0];
    // 2.启动线程
    [thread start];
  • 主线程相关用法
+ (NSThread *)mainThread; // 获得主线程
- (BOOL)isMainThread; // 是否为主线程
+ (BOOL)isMainThread; // 是否为主线程

获得当前线程
NSThread *current = [NSThread currentThread];

线程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;
  1. detach/performSelector
    • 优点:简单快捷
    • 缺点:无法对线程进行更详细的设置
// 1.创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"lnj"];

// 1.创建线程
// 注意: Swift中不能使用, 苹果认为这个方法不安全

// 隐式创建并启动线程
[self performSelectorInBackground:@selector(demo:) withObject:@"lnj"];
  • 线程状态

控制线程状态

启动线程
- (void)start; 
// 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态

阻塞(暂停)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 进入阻塞状态
//例:
    // 睡眠5秒钟
    [NSThread sleepForTimeInterval:5];   
    // 从当前时间睡3秒
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];



强制停止线程
+ (void)exit;
// 进入死亡状态

注意:一旦线程停止(死亡)了,就不能再次开启任务


互斥锁

  • 多线程的安全隐患

    • 被锁定的代码同一时刻只能有一个线程执行
  • 互斥锁使用格式:

@synchronized(锁对象) 
{ 
    // 需要锁定的代码  
}
// 解锁
  • 互斥锁的优缺点

    • 优点:能有效防止因多线程抢夺资源造成的数据安全问题
    • 缺点:需要消耗大量的CPU资源
  • 互斥锁注意点

    • 锁定1份代码只用1把锁,用多把锁是无效的
    • 锁定范围越大, 性能越差

  • 线程间的通信

    •   在子线程中加载数据,回到主线程中刷新UI
  • 原子和非原子属性

    • atomic:线程安全,需要消耗大量的资源
    • nonatomic:非线程安全,适合内存小的移动设备
  • 自旋锁 & 互斥锁

    • 共同点
      • 都能够保证同一时间,只有一条线程执行锁定范围的代码
    • 不同点
      • 互斥锁:如果发现有其他线程正在执行锁定的代码,线程会进入"休眠"状态,等待其他线程执行完毕,打开锁之后,线程会被"唤醒"
      • 自旋锁:如果发现有其他线程正在执行锁定的代码,线程会"一直等待"锁定代码执行完成! 自旋锁更适合执行非常短的代码
posted @ 2016-01-03 21:44  王晓栋  阅读(144)  评论(0编辑  收藏  举报