标签:循环 对象 可变 休眠 用户 实现 成员变量 size 自旋锁
nonatomic
: 非原子属性; atomic
: 原子属性; write
,多个线程可以读取read
;atomic
本身就有一把锁,自旋锁
。nonatomic
和atomic
对比:nonatomic
: 非线程安全,适合内存小的移动设备; atomic
: 线程安全,需要消耗大量的资源.性能比非原子属性要差。nonatomic
,性能更高;1./// 非原子属性
2.@property (nonatomic,strong) NSObject *obj1;
3./// 原子属性:内部有"自旋锁"
4.@property (atomic,strong) NSObject *obj2;
5./// 模拟原子属性
6.@property (atomic,strong) NSObject *obj3;
?了解:
重写非原子属性的setter
和getter
方法:
?了解:
1、重写了原子属性的setter
方法之后,会覆盖原子属性内部的自旋锁
,使其失效;然后我们加入互斥锁
,来模拟单写多读
。
?了解:
2、重写了属性的setter
和getter
方法之后,系统就不会再帮我们生成待下划线的成员变量;使用合成指令@synthesize
,就可以手动的生成带下划线的成员变量。
示例程序:
1.// 合成指令
2.@synthesize obj3 = _obj3;
3.
4./// obj3的setter方法
5.- (void)setObj3:(NSObject *)obj3
6.{
7. @synchronized(self) {
8. _obj3 = obj3;
9. }
10.}
11.
12./// obj3的getter方法
13.- (NSObject *)obj3
14.{
15. return _obj3;
16.}
1./// 测试"非原子属性","互斥锁","自旋锁"的性能
2.- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
3.{
4. NSInteger largeNum = 1000*1000;
5.
6. NSLog(@"非原子属性");
7. CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
8. for (int i = 0; i < largeNum; i++) {
9. self.obj1 = [[NSObject alloc] init];
10. }
11. NSLog(@"非原子属性 => %f",CFAbsoluteTimeGetCurrent()-start);
12.
13. NSLog(@"原子属性");
14. start = CFAbsoluteTimeGetCurrent();
15. for (int i = 0; i < largeNum; i++) {
16. self.obj2 = [[NSObject alloc] init];
17. }
18. NSLog(@"原子属性 => %f",CFAbsoluteTimeGetCurrent()-start);
19.
20. NSLog(@"模拟原子属性");
21. start = CFAbsoluteTimeGetCurrent();
22. for (int i = 0; i < largeNum; i++) {
23. self.obj3 = [[NSObject alloc] init];
24. }
25. NSLog(@"模拟原子属性 => %f",CFAbsoluteTimeGetCurrent()-start);
26.}
互斥锁
:如果发现有其他线程正在执行锁定的代码,线程会进入休眠
状态,等待其他线程执行完毕,打开锁之后,线程会重新进入就绪
状态;等待被CPU重新调度。 自旋锁
:如果发现有其他线程正在执行锁定的代码,线程会以死循环
的方式;一直等待锁定代码执行完成。nonatomic
,原子属性和非原子属性的性能几乎一样。 锁
;无论什么锁,都是有性能消耗的。 NSMutable
的类都是线程不安全的,在做多线程开发的时候,需要注意多线程同时操作可变对象的线程安全问题。标签:循环 对象 可变 休眠 用户 实现 成员变量 size 自旋锁
原文地址:http://www.cnblogs.com/leilifengixng/p/6367511.html