1. Lors de l'apprentissage de la sécurité multithread, j'ai appris à utiliser des verrous de synchronisation pour éviter l'accès "simultané" à la même ressource lorsque plusieurs threads s'exécutent simultanément. Je me suis souvenu que lorsque j'apprenais atomique auparavant, je me souvenais que ce mot-clé est utilisé pour définir si la propriété est thread-safe. J'ai donc désactivé le verrouillage de synchronisation dans le programme et utilisé les mots-clés ci-dessus pour définir la propriété. Cependant, après avoir effectué des opérations multithread, j'ai constaté que ce paramètre n'atteignait pas la sécurité des threads. Puis-je demander où ma compréhension est fausse ?
Mon code de programme est le suivant :
#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
Ce qui suit fait partie de la sortie : veuillez noter que deux 98 sont sortis
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!