在多個(gè)線程搶奪資源的時(shí)候,才需要加鎖
- (void)viewDidLoad {
[super viewDidLoad];
self.lock = [[NSObject alloc]init];
//設(shè)置總票數(shù)
self.totalCount = 100;
//初始化售票員(創(chuàng)建線程對(duì)象)
self.thread01 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread02 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread03 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
//設(shè)置名稱
self.thread01.name = @"售票員小妹A";
self.thread02.name = @"售票員小妹B";
self.thread03.name = @"售票員小妹C";
//啟動(dòng)線程
[self.thread01 start];
[self.thread02 start];
[self.thread03 start];
}
-(void)saleTicket {
while (1) {
//為代碼添加同步鎖(互斥鎖)
/*
* token:鎖對(duì)象 (要使用全局的對(duì)象) 建議直接使用self
* {} 要加鎖的代碼段
* 注意點(diǎn):①加多把鎖是無效的②要注意加鎖的位置
*/
//線程A
//線程C (排隊(duì))
//線程B 如果鎖對(duì)象是狀態(tài)是關(guān)閉的,那么線程B進(jìn)入阻塞狀態(tài)(等待)
//當(dāng)鎖打開之后,會(huì)主動(dòng)喚醒排隊(duì)的線程(B)
@synchronized(self) {
//售票 檢查余票-如果有票賣出一張,否則提示用戶
NSInteger count = self.totalCount;
if (count >0) {
//賣票
self.totalCount = count - 1;
for (int i = 0; i < 10000000; ++i) {
}
NSLog(@"%@賣出去了一張票,還剩下%zd張票",[NSThread currentThread].name,self.totalCount);
} else {
//提示用戶票已經(jīng)賣完
NSLog(@"%@發(fā)現(xiàn)票已經(jīng)賣完啦",[NSThread currentThread].name);
break;
}
}
}
}
@end
在開發(fā)中,多線程搶奪資源的情況并不多,定義屬性的時(shí)候不寫,默認(rèn)是原子屬性的
這么配置下就允許發(fā)送http請(qǐng)求
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
/*
App Transport Security Settings
Allow Arbitrary Loads YES -- 這么設(shè)置就允許發(fā)送http請(qǐng)求
*/
#pragma mark -----------------------
#pragma mark Events
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//創(chuàng)建子線程(3種方法)
[NSThread detachNewThreadSelector:@selector(download) toTarget:self withObject:nil];
}
#pragma mark -----------------------
#pragma mark Methods
-(void)download {
NSLog(@"download----%@",[NSThread currentThread]);
//01 確定URL地址
NSURL *url = [NSURL URLWithString:@"http://image.tianjimedia.com/uploadImages/2015/083/30/VVJ04M7P71W2.jpg"];
//02 把圖片的二進(jìn)制數(shù)據(jù)下載到本地
NSData *imageData = [NSData dataWithContentsOfURL:url];
//03 把圖片的二進(jìn)制格式轉(zhuǎn)換為UIimage
UIImage *image = [UIImage imageWithData:imageData];
//報(bào)錯(cuò):把和UI相關(guān)的操作放在后臺(tái)線程中處理
//04 回到主線程顯示圖片
//子線程切換回主線程
/* 參數(shù)說明
*
* 第一個(gè)參數(shù):方法選擇器 回到主線程要做什么(方法)
* 第二個(gè)參數(shù):調(diào)用函數(shù)需要傳遞的參數(shù)
* 第三個(gè)參數(shù):是否等待該方法(方法選擇器的方法)執(zhí)行完畢才繼續(xù)往下執(zhí)行 YES:等待
*/
//第一種方法
//[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
//第二種方法
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
//簡便方法
//[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
NSLog(@"_____end______");
}
-(void)showImage:(UIImage *)image {
//NSLog(@"UI----%@",[NSThread currentThread]);
for (int i = 0; i < 100; ++i) {
NSLog(@"%zd---",i);
}
self.imageView.image = image;
}
#pragma mark -----------------------
#pragma mark 計(jì)算代碼段執(zhí)行時(shí)間的兩種方法
-(void)timer {
NSDate *start = [NSDate date]; //獲得當(dāng)前的時(shí)間
//01 確定URL地址
NSURL *url = [NSURL URLWithString:@"http://image.tianjimedia.com/uploadImages/2015/083/30/VVJ04M7P71W2.jpg"];
NSDate *end = [NSDate date]; //獲得當(dāng)前的時(shí)間
NSLog(@"%f",[end timeIntervalSinceDate:start]);
//02 把圖片的二進(jìn)制數(shù)據(jù)下載到本地
NSData *imageData = [NSData dataWithContentsOfURL:url];
//03 把圖片的二進(jìn)制格式轉(zhuǎn)換為UIimage
UIImage *image = [UIImage imageWithData:imageData];
//04 顯示圖片
self.imageView.image = image;
}
-(void)timer2 {
CFTimeInterval start = CFAbsoluteTimeGetCurrent();//獲得當(dāng)前時(shí)間(相對(duì)時(shí)間)
//01 確定URL地址
NSURL *url = [NSURL URLWithString:@"http://image.tianjimedia.com/uploadImages/2015/083/30/VVJ04M7P71W2.jpg"];
CFTimeInterval end = CFAbsoluteTimeGetCurrent();//獲得當(dāng)前時(shí)間(相對(duì)時(shí)間)
NSLog(@"%f",end - start);
//02 把圖片的二進(jìn)制數(shù)據(jù)下載到本地
NSData *imageData = [NSData dataWithContentsOfURL:url];
//03 把圖片的二進(jìn)制格式轉(zhuǎn)換為UIimage
UIImage *image = [UIImage imageWithData:imageData];
//04 顯示圖片
self.imageView.image = image;
}
@end