多线程编程

线程死锁:当线程访问一个资源时,如果该资源已经被其他进程正在访问(已加锁),如果想要使用该资源,必须等其他资源解锁完毕,如果不解锁,线程处于长期等待状态.
线程互斥:当多个线程访问同一块资源时,为了保证访问安全,一个线程在访问时,其他线程处于等待状态.
线程同步:线程之间存在依赖关系,后一个线程的执行必须依赖于前一个任务的结束.
线程并发:线程与线程之间不存在依赖关系,同时执行,可能后分配的线程的任务先完成.
子线程完成耗时操作,主线程负责界面显示
队列为每一个任务分配了一个子线程,因为队列是先进先出,所以分配任务时有先后顺序,但是所有任务又是同时进行(线程并发).
任务队列创建的线程数量有系统性能决定,但是能够保证所有的任务君子爱子线程中执行.
网络中的同步连接和异步连接 :
    属于连接方式 , 请求线程不同 : 同步连接网络请求是由主线程处理 , 而异步连接是由子线程处理 .
    线程同步和线程并发 :
    属于多线程之间的关系 . 线程同步 : 各线程执行的任务之间存在依赖关系 , 后一个线程执行任务必须等待前一个线程执行任务结束 .
    线程并发 : 线程同时执行任务 , 线程执行的任务之间没有依赖关系 , 可能后执行任务的线程先完成任务 .
    主线程和子线程都可以实现线程同步 , 但是只有子线程能够实现线程并发 .

@interface AppDelegate ()
{
    NSInteger _totalTickets; // 剩余票数
    NSLock *_lock; // 存储加锁对象
}
@end

@implementation AppDelegate
- ( void )test1:( NSString *)name {
    // 子线程中没有自动释放池
    NSLog ( @"fan test1 = %@, isMainThread = %d" ,[ NSThread currentThread ],[[ NSThread currentThread ] isMainThread ]);
    for (int i = 0; i < 10; i++) {
      NSLog(@"%d", i);
   }
    // 定时器在主线程中能够响应对应的方法 , 但是在子线程中不能 .
    // 原因 : 主线程在 UIApplicationMain 函数中开启了事件循环 , 能够及时捕获操作 , 及时处理 , 但是在子线程中并没有开启事件循环 .
    @autoreleasepool {
        [ NSTimer scheduledTimerWithTimeInterval : 1 target : self selector : @selector (aa) userInfo : nil repeats : YES ];
        // 获取当前线程中的事件循环
        NSRunLoop *loop = [ NSRunLoop currentRunLoop ];
        // 开启事件循环 .
        [loop run ];
    }
}
- ( void )aa {
    NSLog ( @"lanou" );
}
- ( void )test2 {
    NSLog ( @"fan test2 = %@, isMainThread = %d" ,[ NSThread currentThread ],[[ NSThread currentThread ] isMainThread ]);
    for ( int i = 0 ; i< 1000 ; i++) {
        NSLog ( @"Duck is duck" );
    }
}
- ( void )sellTicket:( NSString *)name {
  线程互斥 : 当多个线程访问同一块资源时 , 为了保证访问安全 , 一个线程在访问时 , 其他线程处于等待状态 .

线程死锁 : 当线程访问一个资源时 , 如果该资源已经被其他线程正在访问 ( 已加锁 ), 如果想要使用该资源 , 必须等其他线程解锁完毕 , 如果不解锁 , 线程处于长期等待状态 .
    @autoreleasepool {
        while ( YES ) {
            [ _lock lock ]; // 加锁 .
            if ( _totalTickets > 0 ) {
                _totalTickets --;
                NSLog ( @"%@ 剩余票数为 %d" , name, _totalTickets );
            } else {
                NSLog ( @"%@ 票已卖完 " , name);
                break ;
            }
            //[_lock unlock]; // 解锁
        }
    }
}
- ( BOOL )application:( UIApplication *)application didFinishLaunchingWithOptions:( NSDictionary *)launchOptions {
   
    self . window = [[ UIWindow alloc ] initWithFrame :[[ UIScreen mainScreen ] bounds ]];
    [ _window release ];
    // 主线程中
   
    // 创建子线程 , 完成 test1 操作
    // 子线程完成耗时操作 , 主线程负责界面显示 .
    //1. 创建子线程的方式 , 使用 NSThread 创建线程
//    [NSThread detachNewThreadSelector:@selector(test1) toTarget:self withObject:nil];
    //2. 创建子线程方式 , 使用 NSTread 添加线程任务 .
//    NSThread *tread = [[NSThread alloc] initWithTarget:self selector:@selector(test1) object:nil];
//    [tread start]; // 执行任务 , 此时才会开辟子线程
    //3. 创建子线程方式 , 将任务添加到 NSOperationQueue( 任务队列 , 先进先出 ) , 由队列针对于所有的任务合理的分配线程 .
//    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test1) object:self];
//    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test2) object:self];
    // 添加到任务队列中
    // 队列为每一任务分配了一个子线程 , 因为队列是先进先出 , 所以分配任务时有先后顺序 , 但是所有任务又是同时进行 ( 线程并发 ),
    // 线程同步 : 线程之间存在依赖关系 , 后一个线程的执行必须依赖于前一个任务的结束 .
    // 线程并发 : 线程与线程之间不存在依赖关系 , 同时执行 , 可能后分配的线程的任务先完成 .
    // 任务队列创建的线程数量由系统性能决定 . 但是能够保证所有的任务均在子线程中执行 .
    //NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 设置最大并发数 , 同一时间允许执行的任务数 .
    //[queue setMaxConcurrentOperationCount:1];
    // 添加任务之间的依赖关系
    //[operation2 addDependency:operation1];
    //[queue addOperation:operation1];
    //[queue addOperation:operation2];
    //[operation1 release];
    //[operation2 release];
    //[queue release];
   
    //4. 使用 NSObject 分类中提供了创建子线程的方法
    //[self performSelectorInBackground:@selector(test1:) withObject:@"fgj"];
   
//    _totalTickets = 30; // 剩余票数
//    _lock = [[NSLock alloc] init];
   
    // 模拟售票
//    [NSThread detachNewThreadSelector:@selector(sellTicket:) toTarget:self withObject:@"chao"];
//    [NSThread detachNewThreadSelector:@selector(sellTicket:) toTarget:self withObject:@"qing"];
   
    UIImageView *imageView = [[ UIImageView alloc ] initWithFrame : self . window . bounds ];
    imageView. backgroundColor = [ UIColor yellowColor ];
    imageView. tag = 100 ;
    [ self . window addSubview :imageView];
    [imageView release ];
   
    // 类似于网络请求等耗时操作 , 交有子线程去处理 .
    [ self performSelectorInBackground : @selector (downLoadImage) withObject : nil ];
   
    self . window . backgroundColor = [ UIColor redColor ];
    [ self . window makeKeyAndVisible ];
    return YES ;
}

- ( void )downLoadImage {
    NSLog ( @"%@, isMainThread = %d" ,[ NSThread currentThread ],[[ NSThread currentThread ] isMainThread ]);
    UIImage *image = [ UIImage imageWithData :[ NSData dataWithContentsOfURL :[ NSURL URLWithString : @" http://image.zcool.com.cn/56/13/1308200901454.jpg " ]]];
    // 刷新 UI 界面的操作交由主线程去处理 .
    // 从子线程中跳到主线程中 , 处理 UI
    [ self performSelectorOnMainThread : @selector (loadImage:) withObject :image waitUntilDone : YES ];
}
- ( void )loadImage:( UIImage *)image {
    NSLog ( @"%@" ,[ NSThread currentThread ]);
    UIImageView *imageView = ( UIImageView *)[ self . window viewWithTag : 100 ];
    imageView. image = image;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值