1.在学习多线程安全的时候 学到了使用同步锁来避免多条线程并发执行时“同时”访问同一资源的情况。我想起了 之前学习atomic时,想起了该关键字是用来设置属性是否是线程安全的。于是我在程序中关闭了同步锁,并使用了上面的关键字来定义property 可是我在执行多线程操作后,发现这个设置并没有达到线程安全的效果。 请问是我的理解哪里出现了偏差了呢?
我的程序代码如下:
#import "ThreadSafeVC.h" @interface ThreadSafeVC () //售票员01 @property (nonatomic, strong) NSThread *thread01; //售票员02 @property (nonatomic, strong) NSThread *thread02; //售票员03 @property (nonatomic, strong) NSThread *thread03; //火车票 @property (atomic, assign) NSInteger totalTicket; @end @implementation ThreadSafeVC - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"线程安全"; _totalTicket = 100;//假设有100张火车票 [self createSubThreadsSaleTicket]; } //创建子线程,售票 - (void)createSubThreadsSaleTicket { _thread01 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; _thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; _thread03 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; [_thread01 setName:@"售票员01"]; [_thread02 setName:@"售票员02"]; [_thread03 setName:@"售票员03"]; //开启线程 [_thread01 start]; [_thread02 start]; [_thread03 start]; } - (void)saleTicket { while (true) { //添加 互斥锁 // @synchronized (self)//这里有一个疑问 就是我将_totalTicket 设置成@property(atomic,xxxxx)的时候,关闭了这里的同步锁,发现依然线程不安全 // { [NSThread sleepForTimeInterval:0.03]; if (_totalTicket > 0) { _totalTicket--; NSLog(@"%----@---卖出了---%zd张---火车票", [NSThread currentThread].name, _totalTicket); } else { break; } // } } } @end
下面是部分输出结果: 请留意输出了 两个 98
2016-08-28 19:25:04.893 GYBase[2527:39769] 售票员01---卖出了---99张---火车票 2016-08-28 19:25:04.893 GYBase[2527:39771] 售票员03---卖出了---98张---火车票 2016-08-28 19:25:04.893 GYBase[2527:39770] 售票员02---卖出了---98张---火车票 2016-08-28 19:25:04.925 GYBase[2527:39770] 售票员02---卖出了---96张---火车票 2016-08-28 19:25:04.925 GYBase[2527:39771] 售票员03---卖出了---96张---火车票 2016-08-28 19:25:04.925 GYBase[2527:39769] 售票员01---卖出了---95张---火车票 2016-08-28 19:25:04.957 GYBase[2527:39770] 售票员02---卖出了---94张---火车票 2016-08-28 19:25:04.958 GYBase[2527:39769] 售票员01---卖出了---93张---火车票 2016-08-28 19:25:04.958 GYBase[2527:39771] 售票员03---卖出了---92张---火车票 2016-08-28 19:25:04.987 GYBase[2527:39770] 售票员02---卖出了---91张---火车票 2016-08-28 19:25:04.989 GYBase[2527:39769] 售票员01---卖出了---90张---火车票 2016-08-28 19:25:04.989 GYBase[2527:39771] 售票员03---卖出了---89张---火车票 2016-08-28 19:25:05.017 GYBase[2527:39770] 售票员02---卖出了---88张---火车票 2016-08-28 19:25:05.019 GYBase[2527:39769] 售票员01---卖出了---87张---火车票 2016-08-28 19:25:05.019 GYBase[2527:39771] 售票员03---卖出了---86张---火车票 2016-08-28 19:25:05.052 GYBase[2527:39771] 售票员03---卖出了---84张---火车票 2016-08-28 19:25:05.052 GYBase[2527:39770] 售票员02---卖出了---84张---火车票 2016-08-28 19:25:05.052 GYBase[2527:39769] 售票员01---卖出了---83张---火车票 2016-08-28 19:25:05.082 GYBase[2527:39771] 售票员03---卖出了---82张---火车票 2016-08-28 19:25:05.082 GYBase[2527:39770] 售票员02---卖出了---82张---火车票
_totalTicket--
是对实例变量直接进行操作而不经过setter getter方法,而加了atomic特质的属性,会在对属性读写的时候进行加锁保证线程安全,如下所以你应该用.语法去访问。但atomic并不是绝对线程安全的
相关资料
哦。多谢你的回答。感觉这个atomic有些差强人意了。我在好好看看。多谢!