网络开始---多线程---线程的安全问题(了解)(四)
1 //
2 /**
3 * 线程的注意点
4 1.不要同时开太多线程,(1-3条即可,最多不要超过5条)
5
6 线程概念:
7 1.主线程: UI线程,显示、刷新UI界面、处理UI控件的事件
8 2.子线程(异步线程、后台线程)
9
10 3.不要把耗时的操作放在主线程,要放在子线程中执行
11
12
13 这里是3个窗口卖票的案例
14 */
15
16 #import "HMViewController.h"
17
18 @interface HMViewController ()
19 //3个窗口3条线程
20 @property (nonatomic, strong) NSThread *thread1;
21 @property (nonatomic, strong) NSThread *thread2;
22 @property (nonatomic, strong) NSThread *thread3;
23
24 /**
25 * 剩余票数
26 */
27 @property (nonatomic, assign) int leftTicketCount;
28
29
30 //锁对象,用一把锁,不要经常换锁,才能保证线程的安全
31 //@property (nonatomic, strong) NSObject *locker;
32 @end
33
34 @implementation HMViewController
35
36 - (void)viewDidLoad
37 {
38 [super viewDidLoad];
39
40 //开始剩余的票数为50张
41 self.leftTicketCount = 50;
42
43 //创建线程
44 self.thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
45 //线程名称
46 self.thread1.name = @"1号窗口";
47
48 self.thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
49 self.thread2.name = @"2号窗口";
50
51 self.thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
52 self.thread3.name = @"3号窗口";
53
54 // self.locker = [[NSObject alloc] init];
55 }
56
57 //点击启动线程 3个窗口同时开始卖票,
58 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
59 {
60 [self.thread1 start];
61 [self.thread2 start];
62 [self.thread3 start];
63 }
64
65 /**
66 * 卖票
67 */
68 - (void)saleTicket
69 {
70 while (1) { //写个死循环一直卖,卖光为止
71
72 // ()小括号里面放的是锁对象 括号里面用self就行了,标示唯一的一把锁
73
74 @synchronized(self) {// 开始加锁 叫做互斥锁
75
76 //保证一个线程访问资源时其他线程不能访问该资源,只要使用@synchronized这个关键字即可枷锁,保证线程的安全
77
78 //多条线程抢夺同一块资源时才需要加锁,要不然非常耗费CPU资源
79 //线程同步:按顺序的执行任务,线程同步问题就 加锁 解决问题
80 //互斥锁就是使用了线程同步技术
81
82 //取出剩余的票数
83 int count = self.leftTicketCount;
84 //如果票数大于0
85 if (count > 0) {
86 [NSThread sleepForTimeInterval:0.05];
87
88 //剩余的票数-1
89 self.leftTicketCount = count - 1;
90
91 NSLog(@"%@卖了一张票, 剩余%d张票", [NSThread currentThread].name, self.leftTicketCount);
92 } else { //如果票数为0,退出循环
93
94 return; // 退出循环
95
96 }
97 } // 解锁
98 }
99 }
100
101 @end