iOS 多线程同步策略之-----锁NSLock和@synchronized

时间:2021-01-01 13:01:16

1.NSLock---锁同步

- (void)viewDidLoad
{
[super viewDidLoad];
NSLock * lock = [[NSLock alloc]init];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
[self method1];
[lock unlock];
});

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
[self method2];
[lock unlock];
});

}
- (void)method1{

NSLog(@"%@",NSStringFromSelector(_cmd));

NSLog(@" method 1 Current thread = %@", [NSThread currentThread]);

NSLog(@"method 1 Main thread = %@", [NSThread mainThread]);

}


- (void)method2{

NSLog(@"%@",NSStringFromSelector(_cmd));

NSLog(@"method 2 Current thread = %@", [NSThread currentThread]);

NSLog(@" method 2 Main thread = %@", [NSThread mainThread]);

}

2.@synchronized(obj)  //obj 同步对象

{

}

Objective-C支持程序中的多线程。这就意味着两个线程有可能同时修改同一个对象,这将在程序中导致严重的问题。为了避免这种多个线程同时执行同一段代码的情况,Objective-C提供了@synchronized()指令。

指令@synchronized()通过对一段代码的使用进行加锁。其他试图执行该段代码的线程都会被阻塞,直到加锁线程退出执行该段被保护的代码段,也就是说@synchronized()代码块中的最后一条语句已经被执行完毕的时候。

指令@synchronized()需要一个参数。该参数可以使任何的Objective-C对象,包括self。这个对象就是互斥信号量。他能够让一个线程对一段代码进行保护,避免别的线程执行该段代码。针对程序中的不同的关键代码段,我们应该分别使用不同的信号量。只有在应用程序编程执行多线程之前就创建好所有需要的互斥信号量对象来避免线程间的竞争才是最安全的。


-》使用self作为互斥信号量来实现当前对象对实例方法访问的同步。

- (void)viewDidLoad
{
[super viewDidLoad];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self)
{
[self method1];
}

});

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self)
{
[self method2];
}
});

}


-》使用自定义的信号量来对方法加锁

    Account *account = [AccountaccoutFromString :[accountFiled stringValue]];  

//获取信号量
id accountSemaphore = [Account semaphore];
@synchronized(accountSemaphore)
{
//关键代码
}