objektif-c - Saya ingin bertanya beberapa soalan tentang pemahaman kata kunci atom @property.
大家讲道理
大家讲道理 2017-05-02 09:29:14
0
2
590

1. Apabila mempelajari keselamatan berbilang benang, saya belajar menggunakan kunci penyegerakan untuk mengelakkan akses "serentak" kepada sumber yang sama apabila berbilang rangkaian dijalankan serentak. Saya teringat bahawa semasa saya belajar atom sebelum ini, saya teringat bahawa kata kunci ini digunakan untuk menetapkan sama ada sifat itu selamat untuk benang. Oleh itu, saya mematikan kunci penyegerakan dalam program dan menggunakan kata kunci di atas untuk menentukan sifat Walau bagaimanapun, selepas melakukan operasi berbilang benang, saya mendapati bahawa tetapan ini tidak mencapai keselamatan benang. Boleh saya tanya di mana silap pemahaman saya?

Kod program saya adalah seperti berikut:

#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

Berikut adalah sebahagian daripada output: Sila ambil perhatian bahawa dua 98 adalah output

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

光阴似箭催人老,日月如移越少年。

membalas semua(2)
小葫芦

_totalTicket-- adalah untuk mengendalikan pembolehubah contoh secara langsung tanpa melalui kaedah pengumpul penetap, dan menambah atribut atom, yang akan dikunci apabila membaca dan menulis atribut untuk memastikan keselamatan benang, seperti berikut

atomic的实现:
- (void)setCurrentImage:(UIImage *)currentImage
{
    @synchronized(self) {
        if (_currentImage != currentImage) {
            [_currentImage release];
            _currentImage = [currentImage retain];
                    
            // do something
        }
    }
}

- (UIImage *)currentImage
{
    @synchronized(self) {
        return _currentImage;
    }
}

Jadi anda harus menggunakan sintaks untuk mengakses. Tetapi atomic tidak sepenuhnya selamat untuk benang
Maklumat berkaitan

我想大声告诉你

Oh. Terima kasih atas jawapan anda. Saya merasakan bahawa atom ini agak tidak memuaskan. Saya sedang melihat baik-baik. terima kasih!

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan