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--
consiste à faire fonctionner les variables d'instance directement sans passer par la méthode setter getter, et ajoute des attributs atomiques, qui se verrouilleront lors de la lecture et de l'écriture des attributs pour garantir la sécurité des threads, comme suitVous devez donc utiliser la syntaxe . Mais atomique n'est pas absolument thread-safe
Informations associées
Oh. Merci pour votre réponse. Je pense que cet atomique est un peu insatisfaisant. Je regarde bien. Merci!