0422 线程同步/同步锁防止脏数据
如果不加同步锁,代码如下:
#import "ViewController.h"
@interface ViewController ()
{
NSInteger _money;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_money = 100;
NSThread *t1 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
NSThread *t2 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
NSThread *t3 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
NSThread *t4 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
t1.name = @"我是--t1";
t2.name = @"我是--t2";
t3.name = @"我是--t3";
t4.name = @"我是--t4";
[t1 start];
[t2 start];
[t3 start];
[t4 start];
}
-(void)doThing{
@interface ViewController ()
{
NSInteger _money;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_money = 100;
NSThread *t1 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
NSThread *t2 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
NSThread *t3 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
NSThread *t4 = [[NSThread alloc]initWithTarget:self selector:@selector(doThing) object:nil];
t1.name = @"我是--t1";
t2.name = @"我是--t2";
t3.name = @"我是--t3";
t4.name = @"我是--t4";
[t1 start];
[t2 start];
[t3 start];
[t4 start];
}
-(void)doThing{
for(int i=0;i<3;i++){
[self getMoney:10];
}
}
-(void)getMoney:(NSInteger)money{
// 查余额
if(_money >= money){
[NSThread sleepForTimeInterval:2];
_money -= money;
NSLog(@"%@----余额 : %ld",[NSThread currentThread],_money);
-(void)getMoney:(NSInteger)money{
// 查余额
if(_money >= money){
[NSThread sleepForTimeInterval:2];
_money -= money;
NSLog(@"%@----余额 : %ld",[NSThread currentThread],_money);
}
}
// 打印结果,有随机性: 明显脏数据
![](https://app.yinxiang.com/shard/s21/res/9eb829c3-5630-4f44-a9af-d880c95de02e.png)
// 改进:
线程锁:
1. 创建锁对象NSLock,并实例化
_lockCondition = [[NSLock alloc]init];
2. 判断是否有锁,没有就进入并锁住.
if ([_lockCondition tryLock]) {
// 在里面做取钱操作
// 取钱完成后解锁
[_lockCondition unlock];
}
改进后:总共12次,只有4次取钱操作成功了.
![](https://app.yinxiang.com/shard/s21/res/3e35f7c8-862c-4cf4-b793-a328d4f5176a.png)
// 需求: 如果确实要取完钱为止
应该按如下方式:
//加锁,操作完成后解锁.
![](https://app.yinxiang.com/shard/s21/res/790a9192-4215-422d-9799-f0e291729cee.png)
// 可见: 加锁后, 操作者和操作线程都是有序的...
![](https://app.yinxiang.com/shard/s21/res/cfe98934-44fc-4d87-ba18-b05e9bd1a411.png)