线程安全的概念是,当多个线程同时访问一个资源时,要确保资源的准确性。也就是说,多个线程必须同步访问一块资源……安全
实现线程安全就是加锁。加锁,锁定的代码要尽可能少。加锁范围内的代码,同一时间只容许一个线程执行。互斥锁@synchronized (self)的参数,任何继承NSObject的对象均可以,如:self。要保证这个锁对象,全部的线程都能访问到,并且全部线程访问的是同一个锁对象。多线程
线程实现同步的两种锁:(互斥锁与自旋锁的概念在“区别”中有定义)性能
1,互斥锁atom
2,自旋锁线程
共同点:设计
可以锁定一段代码,同一时间,只有一个线程可以执行这段锁定的代码。code
区别:对象
互斥锁:在锁定的时候,其余线程会进入睡眠状态,等待条件知足时,从新唤醒。(当A线程在线程池中,CUP进行处理时,其余线程会从线程池出来,进入睡眠状态,等待唤醒)继承
自旋锁:在锁定的时候,其余线程会进入一个死循环,也是一直在等待条件知足,一旦条件知足,当即执行,少了一个唤醒过程。(当A线程在线程池中,CPU进行处理时,其余线程还在线程池里面)资源
就由于自旋锁少了一个唤醒线程的过程,因此自旋锁的效率要比互斥锁高那么一点点。所以咱们在锁定一段代码时,写@synchronized(self){}的时候,在Xcode中并不会有提示,缘由是苹果不推荐加锁,加锁性能太差!
在定义属性时,如:@property(atomic, strong) NSObject *obj; 其关键字atomic为原子性,(默认的属性就为原子属性),原子性就是为多线程设计的,原子性实现单(线程)写多(线程)读。由于写的安全级别要求更高,读的要求低一些,能够多读几回确保数据的正确性。
在下面重写了setter和getter方法:若是同时重写了setter方法和getter方法,“_成员变量”就不会提供,就可使用合成指令@synthesize,告诉编译器属性成员变量的名称:
@synthesize obj = _obj;
- (void)setObj:(NSObject *)obj
{
@synchronized (self){ //模拟锁。真实状况下,使用的不是互斥锁。原子属性内部使用的是自旋锁……
_obj = obj;
}
}
- (NSObject *)Obj
{
return _obj;
}
UI线程,咱们通常可称为主线程。UIKit中绝大部分类,都不是“线程安全”的。怎么解决这个线程不安全的问题?苹果约定,全部程序更新UI都在主线程中进行,也就不会出现多个线程同时改变一个资源。
在主线程中更新UI,有什么好处?
1,在主线程中更新UI,就不会出现多个线程同时改变同一个UI控件。
2,主线程优先级最高,也就意味着UI的更新优先级高,让用户感受运行很流畅。