iOS 線程安全之@synchronized的用法

@synchronized(self)的用法:

@synchronized 的做用是建立一個互斥鎖,保證此時沒有其它線程對self對象進行修改。這個是objective-c的一個鎖定令牌,防止self對象在同一時間內被其它線程訪問,起到線程的保護做用。objective-c

 

例如:一個電影院,有3個售票員。一場電影的總數量固定。3個售票員售票時,要判斷是非還有餘票。atom

#import "ViewController.h"

@interface ViewController ()
/** 售票員01 */
@property (nonatomic, strong) NSThread *thread01;
/** 售票員02 */
@property (nonatomic, strong) NSThread *thread02;
/** 售票員03 */
@property (nonatomic, strong) NSThread *thread03;

/** 票的總數 */
@property (nonatomic, assign) NSInteger ticketCount;

/** 鎖對象 */
//@property (nonatomic, strong) NSObject *locker;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
//    self.locker = [[NSObject alloc] init];
    
    self.ticketCount = 100;
    
    self.thread01 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    self.thread01.name = @"售票員01";
    
    self.thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    self.thread02.name = @"售票員02";
    
    self.thread03 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    self.thread03.name = @"售票員03";
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.thread01 start];
    [self.thread02 start];
    [self.thread03 start];
}

- (void)saleTicket
{
    while (1) {
        @synchronized(self) {
            // 先取出總數
            NSInteger count = self.ticketCount;
            if (count > 0) {
                self.ticketCount = count - 1;
                NSLog(@"%@賣了一張票,還剩下%zd張", [NSThread currentThread].name, self.ticketCount);
            } else {
                NSLog(@"票已經賣完了");
                break;
            }
        }
    }
}

@end
相關文章
相關標籤/搜索