• 线程同步


    我们演示一个经典的卖票的例子来讲NSThread的线程同步:

    1. #import <UIKit/UIKit.h>  
    2.   
    3. @class ViewController;  
    4.   
    5. @interface AppDelegate : UIResponder <UIApplicationDelegate>  
    6. {  
    7.     int tickets;  
    8.     int count;  
    9.     NSThread* ticketsThreadone;  
    10.     NSThread* ticketsThreadtwo;  
    11.     NSCondition* ticketsCondition;  
    12.     NSLock *theLock;  
    13. }  
    14. @property (strong, nonatomic) UIWindow *window;  
    15.   
    16. @property (strong, nonatomic) ViewController *viewController;  
    17.   
    18. @end  
    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
    2. {  
    3.       
    4.     tickets = 100;  
    5.     count = 0;  
    6.     theLock = [[NSLock alloc] init];  
    7.     // 锁对象  
    8.     ticketsCondition = [[NSCondition alloc] init];  
    9.     ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];  
    10.     [ticketsThreadone setName:@"Thread-1"];  
    11.     [ticketsThreadone start];  
    12.       
    13.       
    14.     ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];  
    15.     [ticketsThreadtwo setName:@"Thread-2"];  
    16.     [ticketsThreadtwo start];  
    17.       
    18.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
    19.     // Override point for customization after application launch.  
    20.     self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];  
    21.     self.window.rootViewController = self.viewController;  
    22.     [self.window makeKeyAndVisible];  
    23.     return YES;  
    24. }  
    25.   
    26. - (void)run{  
    27.     while (TRUE) {  
    28.         // 上锁  
    29. //        [ticketsCondition lock];  
    30.         [theLock lock];  
    31.         if(tickets >= 0){  
    32.             [NSThread sleepForTimeInterval:0.09];  
    33.             count = 100 - tickets;  
    34.             NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);  
    35.             tickets--;  
    36.         }else{  
    37.             break;  
    38.         }  
    39.         [theLock unlock];  
    40. //        [ticketsCondition unlock];  
    41.     }  
    42. }  

    如果没有线程同步的lock,卖票数可能是-1.加上lock之后线程同步保证了数据的正确性。
    上面例子我使用了两种锁,一种NSCondition ,一种是:NSLock。 NSCondition我已经注释了。

    线程的顺序执行

    他们都可以通过

            [ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。

    比如:

     

    1. #import "AppDelegate.h"  
    2.   
    3. #import "ViewController.h"  
    4.   
    5. @implementation AppDelegate  
    6.   
    7. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
    8. {  
    9.       
    10.     tickets = 100;  
    11.     count = 0;  
    12.     theLock = [[NSLock alloc] init];  
    13.     // 锁对象  
    14.     ticketsCondition = [[NSCondition alloc] init];  
    15.     ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];  
    16.     [ticketsThreadone setName:@"Thread-1"];  
    17.     [ticketsThreadone start];  
    18.       
    19.     ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];  
    20.     [ticketsThreadtwo setName:@"Thread-2"];  
    21.     [ticketsThreadtwo start];  
    22.       
    23.     NSThread *ticketsThreadthree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil];  
    24.     [ticketsThreadthree setName:@"Thread-3"];  
    25.     [ticketsThreadthree start];      
    26.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
    27.     // Override point for customization after application launch.  
    28.     self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];  
    29.     self.window.rootViewController = self.viewController;  
    30.     [self.window makeKeyAndVisible];  
    31.     return YES;  
    32. }  
    33.   
    34. -(void)run3{  
    35.     while (YES) {  
    36.         [ticketsCondition lock];  
    37.         [NSThread sleepForTimeInterval:3];  
    38.         [ticketsCondition signal];  
    39.         [ticketsCondition unlock];  
    40.     }  
    41. }  
    42.   
    43. - (void)run{  
    44.     while (TRUE) {  
    45.         // 上锁  
    46.         [ticketsCondition lock];  
    47.         [ticketsCondition wait];  
    48.         [theLock lock];  
    49.         if(tickets >= 0){  
    50.             [NSThread sleepForTimeInterval:0.09];  
    51.             count = 100 - tickets;  
    52.             NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);  
    53.             tickets--;  
    54.         }else{  
    55.             break;  
    56.         }  
    57.         [theLock unlock];  
    58.         [ticketsCondition unlock];  
    59.     }  
    60. }  

    wait是等待,我加了一个 线程3 去唤醒其他两个线程锁中的wait

    其他同步

    我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
    - (void)doSomeThing:(id)anObj
    {
        @synchronized(anObj)
        {
            // Everything between the braces is protected by the @synchronized directive.
        }
    }

  • 相关阅读:
    表的简单增删改查
    数据库基础入门语句
    exports与module.exports的区别
    Spring入门——简介
    Mybatis之动态SQL揭秘
    Mybatis的核心组成部分-SQL映射文件揭秘
    Mybatis框架简介、搭建及核心元素揭秘
    实战讲解:SSM+Maven开发APP信息管理平台-developer版
    OpenCV结构简介
    在Linux服务器上安装lxml
  • 原文地址:https://www.cnblogs.com/codings/p/3567165.html
Copyright © 2020-2023  润新知