찾다

 >  Q&A  >  본문

objective-c - 关于@property 的 atomic关键字的理解 有些问题想请教。

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张---火车票
大家讲道理大家讲道理2757일 전574

모든 응답(2)나는 대답할 것이다

  • 高洛峰

    高洛峰2017-05-02 09:31:14

    _totalTicket--은 setter getter 메소드를 통하지 않고 인스턴스 변수를 직접 조작하고, 다음과 같이 스레드 안전성을 보장하기 위해 속성을 읽고 쓸 때 잠기는 원자 속성을 추가하는 것입니다

    으아아아

    따라서 액세스하려면 . 구문을 사용해야 합니다. 그러나 Atomic은 스레드로부터 절대적으로 안전하지 않습니다
    관련 정보

    회신하다
    0
  • 我想大声告诉你

    我想大声告诉你2017-05-02 09:31:14

    아. 답변해 주셔서 감사합니다. 이번 아토믹은 좀 불만족스럽다고 생각합니다. 잘 보고 있습니다. 감사합니다!

    회신하다
    0
  • 취소회신하다