多线程 线程的安全隐患
Posted 罗小浮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程 线程的安全隐患相关的知识,希望对你有一定的参考价值。
有了多线程就有了资源竞争,当多个线程对同一资源进行操作时就容易出现安全隐患。
下面举一个卖票的例子来说明线程的安全隐患
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
@interface ViewController () @property (assign, nonatomic ) NSInteger tickets; @end @implementation ViewController - ( void )viewDidLoad { [ super viewDidLoad]; //设置票的数量为5 _tickets = 5; //线程一 NSThread *threadOne = [[ NSThread alloc] initWithTarget: self selector: @selector (saleTickets) object: nil ]; threadOne.name = @ "threadOne" ; //线程二 NSThread *threadTwo = [[ NSThread alloc] initWithTarget: self selector: @selector (saleTickets) object: nil ]; //开启线程 [threadOne start]; [threadTwo start]; } - ( void )saleTickets { while (1) { [ NSThread sleepForTimeInterval:1]; if (_tickets > 0) { _tickets--; NSLog (@ "剩余票数= %ld" ,_tickets); } else { NSLog (@ "票卖完了" ); break ; } } } |
打印结果
可以看到票的余量是很混乱的,看下面一张图可以比较清楚的了解为什么会出现这种情况
如何解决?添加互斥锁(当A线程对数据进行操作时(加锁),线程B不能访问当前数据,直到A对数据完成读写操作结束(解锁),线程B才能对数据进行操作)
这样就保证了数据的安全性;
下面是代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
@interface ViewController () @property (assign, nonatomic ) NSInteger tickets; @end @implementation ViewController - ( void )viewDidLoad { [ super viewDidLoad]; //设置票的数量为5 _tickets = 5; //线程一 NSThread *threadOne = [[ NSThread alloc] initWithTarget: self selector: @selector (saleTickets) object: nil ]; threadOne.name = @ "threadOne" ; //线程二 NSThread *threadTwo = [[ NSThread alloc] initWithTarget: self selector: @selector (saleTickets) object: nil ]; //开启线程 [threadOne start]; [threadTwo start]; } - ( void )saleTickets { while (1) { @synchronized ( self ) { [ NSThread sleepForTimeInterval:1]; if (_tickets > 0) { _tickets--; NSLog (@ "剩余票数= %ld" ,_tickets); } else { NSLog (@ "票卖完了" ); break ; } } } } |
打印结果,可以看到数据正常了;
关于代码中用到的@synchronized,它是一个互斥锁,锁的概念将在下一篇中详细讲解
以上是关于多线程 线程的安全隐患的主要内容,如果未能解决你的问题,请参考以下文章