为什么atomic不是线程安全的

原理

1、读取i的值存入寄存器;
2、将i加1;
3、修改i的值;

修改一个属性包含了读,执行 改变,写入,atomic 只为读和写加了锁,保证了同一个时间只有一个线程在读和写,但是,会遇到这种情况
执行改变的代码段并没有加锁,导致了有可能一个线程执行了读之后,还没有进行写,另一个线程进行了读,然后这个线程进行了写,
然后另一个线程也进行了写,导致这个线程的写被另一个线程的写覆盖了

举例子

@property (atomic, assign) NSInteger sliece;

@end

@implementation ThreadSafeController2

- (void)viewDidLoad {
    [super viewDidLoad];
    [self testThreadSafe2];
    // Do any additional setup after loading the view.
}

- (void)testThreadSafe2
{
    dispatch_queue_t queue = dispatch_queue_create("kkk", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (int i = 0; i < 10000; i ++) {
            self.sliece = self.sliece + 1;
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 10000; i ++) {
            self.sliece = self.sliece + 1;
        }
    });
    
    dispatch_after(5, dispatch_get_main_queue(), ^{
        NSLog(@"哈哈值得大小%ld", self.sliece);
    });
}

结果:请添加图片描述

正确的写法

@interface ThreadSafeController2 ()

@property (atomic, assign) NSInteger sliece;

@property (nonatomic, strong) NSLock *lock;

@end

@implementation ThreadSafeController2

- (void)viewDidLoad {
    [super viewDidLoad];
    self.lock = [[NSLock alloc] init];
    [self testThreadSafe2];
    // Do any additional setup after loading the view.
}

- (void)testThreadSafe2
{
    dispatch_queue_t queue = dispatch_queue_create("kkk", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (int i = 0; i < 10000; i ++) {
            [self.lock lock];
            self.sliece = self.sliece + 1;
            [self.lock unlock];
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 10000; i ++) {
            [self.lock lock];
            self.sliece = self.sliece + 1;
            [self.lock unlock];
        }
    });
    
    dispatch_after(5, dispatch_get_main_queue(), ^{
        NSLog(@"哈哈值得大小%ld", self.sliece);
    });
}


请添加图片描述

总结

有以上例子可见,atomic只是在三个步骤中的两个步骤分别加了锁,
但是并不能保证 读和写的锁同时是被一个线程获取之后,然后被其他线程获取 ,可能是线程一获取到锁之后,被线程2获取到锁,
这时候就已经不安全了。
所以我们要保证三个步骤都在锁的范围内

猜你喜欢

转载自blog.csdn.net/LIUXIAOXIAOBO/article/details/133265842