pthread
#import <pthread/pthread.h>
NSString *string = @"pthread";
pthread_t thread;
/**
参数一: 线程对象 传地址
参数二: 线程的属性 (名称\优先级) 可赋值NULL
参数三: 指向函数的指针
参数四: 函数需要接受的字符串参数,可以不传递 可赋值NULL
*/
pthread_create(&thread, NULL, task, (__bridge void *)(string));
void *task (void *param){
NSLog(@"%@---%s---%@",[NSThread currentThread],__func__,param);
//打印结果:{number = 2, name = (null)}---task---pthread
for (NSInteger i =0; i<10000; i++) {
NSLog(@"%zd---%@",i,[NSThread currentThread]);
//打印结果:{number = 2, name = (null)}
if (i == 100) {
pthread_exit(NULL); //退出线程
}
}
return NULL;
}
NSthread
- 创建线程的四种方法
alloc initwith..
|detachNewThread
|performSelectorInBack..
|自定义
- 设置线程的属性(
名称&优先级[0.0~1.0]
)( 默认优先级是0.5 最高的优先级是1.0) - 方法执行完 自动释放
// 1.创建线程,并手动开启
-(void)newThread1{
NSThread *threadA = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"创建线程的第一种方式--线程A"];
[threadA setName:@"线程A"];
[threadA setThreadPriority:1.0];//priority:优先 优先权
[threadA start];
}
// 2.分离出一条子线程 自动开启线程的执行
-(void)newThread2{
[NSThread detachNewThreadSelector:@selector(task) toTarget:self withObject:nil];
}
// 3.开启一条后台线程 自动开启线程的执行
-(void)newThread3{
[self performSelectorInBackground:@selector(task) withObject:nil];
}
// 4.需要自定义NSThread类重写内部的方法实现(重写main)
-(void)newThread4{
//1.创建线程对象
RJThread *thread = [[RJThread alloc]init];
//2.开始
[thread start];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//4秒过后取消线程
[thread cancel];
});
}
-(void)task{
for (NSInteger i = 0; i<1000; i++) {
NSLog(@"%zd--%@",i,[NSThread currentThread].name);
if (i == 50) {
//[NSThread exit]; //强制退出线程
//return; // 任务执行完毕正常退出
//continue; // 进入下一个循环
break; // 跳出循环往下执行
}
}
//NSLog(@"task---%@",[NSThread currentThread]);
NSLog(@"start----");
//阻塞线程(当前的线程)
[NSThread sleepForTimeInterval:2.0]; //阻塞2秒
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];//阻塞3秒
NSLog(@"%@",[NSDate distantFuture]);// 4001-01-01 00:00:00 +0000
NSLog(@"%@",[NSDate distantPast]);//0000-12-30 00:00:00 +0000
NSLog(@"end----");
}
-(void)run:(NSString *)string{
NSLog(@"run--%@--%@",[NSThread currentThread].name,string);
//run--线程A--创建线程的第一种方式--线程A
}
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface RJThread : NSThread
@end
NS_ASSUME_NONNULL_END
----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
#import "RJThread.h"
@implementation RJThread
-(void)main{
NSLog(@"starting thread.......");
NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(doTimerTask) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
//如果当前线程不被取消,则进入循环
while (!self.isCancelled) {
[self doOtherTask];
//如果在doTimerTask中,没有停止RunLoop的操作的话,RunLoop 一直在运行,下面这行代码 永远不会有返回值
//runloop开始执行
BOOL ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
NSLog(@"after runloop counting.........: %d", ret);
}
NSLog(@"finishing thread.........");
}
- (void)doTimerTask{
NSLog(@"do timer task");
// 添加RunLoop停止代码,使NSRunLoop 的runMode:(NSString *)mode beforeDate:(NSDate *)limitDate方法返回
// 停止代码必须在runloop运行接口为runMode:下才能用
// 这行代码写在 timer的触发事件中
CFRunLoopStop(CFRunLoopGetCurrent());
}
- (void)doOtherTask{
NSLog(@"do other task");
}
-(void)dealloc{
NSLog(@"%s",__func__);
}
@end
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[NSThread detachNewThreadSelector:@selector(download) toTarget:self withObject:nil];;
}
-(void)download{
NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1607584191107&di=dabaca87bbdb1c938cebc378ccd85480&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2F201306%2F06%2F144906n0nffsz8h43i1t23.jpg"];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData];
//4.回到主线程设置图片
//方法1
//第三个参数:要不要等待调用方法结束之后再继续往下走
//当为yes的时候,先让主线程运行showImage中的一些操作,之后再进行当前线程中的操作。
//当为no的时候,先进行当前线程中的操作,之后让主线程运行showImage中的一些操作。
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:NO];
//方法2
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];
//方法3
[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
}
-(void)showImage:(UIImage *)image{
self.imageView.image = image;
NSLog(@"UI----%@",[NSThread currentThread]);
}
//方法一
NSDate *start = [NSDate date]; //得到的是程序执行到此处的时间
NSDate *end = [NSDate date]; //得到的是程序执行到此处的时间
NSLog(@"%f",[end timeIntervalSinceDate:start]);
//方法二
CFTimeInterval start = CFAbsoluteTimeGetCurrent();//获得的是绝对时间(参考00:00:00 1 January 2001)
CFTimeInterval end = CFAbsoluteTimeGetCurrent();
NSLog(@"%f",end - start);
@synchronized
// 假设一共8张票
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
for (int i = 0; i < 10; i ++) {
[NSThread detachNewThreadSelector:@selector(saleTicket:) toTarget:self withObject:[NSString stringWithFormat:@"%d",i]];
NSLog(@"============%@",[NSString stringWithFormat:@"%d",i]);
}
}
-(void)saleTicket:(NSString *)string{
/*
同步锁格式:
@synchronized(锁对象){锁住的代码}
锁对象:
1)需要设置一个全局唯一的对象,self
2)锁对象本身是有状态,打开|关闭
注意点:
1)锁定一份代码只能使用同一把锁,
2)加锁的时候要注意位置
3)加锁有前提条件:只有当多个线程存在抢夺同一块资源的时候才需要加锁
4)加锁是需要耗费性能的
5)造成线程同步(多个线程按照固定的顺序来执行任务)
*/
NSLog(@"----------%@",string);
@synchronized(self) {
NSLog(@"++++++++++%@",string);
NSInteger count = self.totalCount;
if (count >0) {
for (NSInteger i = 0; i<100000; i++) {}//演示耗时操作
self.totalCount = count - 1; //卖出去一张票
NSLog(@"%@卖出去了一张票,还剩下%zd张票",[NSThread currentThread].name,self.totalCount);
}else{
NSLog(@"票已经卖光了,做灰机回去吧~");
}
}
}
============<NSThread: 0x6000034cc980>{number = 1, name = main}##0
============<NSThread: 0x6000034cc980>{number = 1, name = main}##1
============<NSThread: 0x6000034cc980>{number = 1, name = main}##2
============<NSThread: 0x6000034cc980>{number = 1, name = main}##3
============<NSThread: 0x6000034cc980>{number = 1, name = main}##4
============<NSThread: 0x6000034cc980>{number = 1, name = main}##5
----------<NSThread: 0x6000034a85c0>{number = 8, name = (null)}##0
============<NSThread: 0x6000034cc980>{number = 1, name = main}##6
============<NSThread: 0x6000034cc980>{number = 1, name = main}##7
============<NSThread: 0x6000034cc980>{number = 1, name = main}##8
============<NSThread: 0x6000034cc980>{number = 1, name = main}##9
----------<NSThread: 0x6000034a8940>{number = 10, name = (null)}##2
++++++++++<NSThread: 0x6000034a85c0>{number = 8, name = (null)}##0
----------<NSThread: 0x6000034a8700>{number = 11, name = (null)}##3
----------<NSThread: 0x6000034a8b80>{number = 13, name = (null)}##5
----------<NSThread: 0x6000034a8bc0>{number = 14, name = (null)}##6
----------<NSThread: 0x6000034a8c00>{number = 15, name = (null)}##7
----------<NSThread: 0x6000034a8c80>{number = 17, name = (null)}##9
----------<NSThread: 0x6000034a8980>{number = 9, name = (null)}##1
卖出去了一张票,还剩下7张票
----------<NSThread: 0x6000034a8b40>{number = 12, name = (null)}##4
++++++++++<NSThread: 0x6000034a8b40>{number = 12, name = (null)}##4
----------<NSThread: 0x6000034a8c40>{number = 16, name = (null)}##8
卖出去了一张票,还剩下6张票
++++++++++<NSThread: 0x6000034a8b80>{number = 13, name = (null)}##5
卖出去了一张票,还剩下5张票
++++++++++<NSThread: 0x6000034a8700>{number = 11, name = (null)}##3
卖出去了一张票,还剩下4张票
++++++++++<NSThread: 0x6000034a8c40>{number = 16, name = (null)}##8
卖出去了一张票,还剩下3张票
++++++++++<NSThread: 0x6000034a8980>{number = 9, name = (null)}##1
卖出去了一张票,还剩下2张票
++++++++++<NSThread: 0x6000034a8c80>{number = 17, name = (null)}##9
卖出去了一张票,还剩下1张票
++++++++++<NSThread: 0x6000034a8940>{number = 10, name = (null)}##2
卖出去了一张票,还剩下0张票
++++++++++<NSThread: 0x6000034a8c00>{number = 15, name = (null)}##7
票已经卖光了,做灰机回去吧~
++++++++++<NSThread: 0x6000034a8bc0>{number = 14, name = (null)}##6
票已经卖光了,做灰机回去吧~
如果去掉@synchronized锁 则结果如下:
============<NSThread: 0x60000092ca40>{number = 1, name = main}##0
============<NSThread: 0x60000092ca40>{number = 1, name = main}##1
----------<NSThread: 0x60000097b100>{number = 7, name = (null)}##0
++++++++++<NSThread: 0x60000097b100>{number = 7, name = (null)}##0
============<NSThread: 0x60000092ca40>{number = 1, name = main}##2
============<NSThread: 0x60000092ca40>{number = 1, name = main}##3
============<NSThread: 0x60000092ca40>{number = 1, name = main}##4
============<NSThread: 0x60000092ca40>{number = 1, name = main}##5
============<NSThread: 0x60000092ca40>{number = 1, name = main}##6
============<NSThread: 0x60000092ca40>{number = 1, name = main}##7
============<NSThread: 0x60000092ca40>{number = 1, name = main}##8
============<NSThread: 0x60000092ca40>{number = 1, name = main}##9
卖出去了一张票,还剩下7张票
----------<NSThread: 0x600000978b00>{number = 8, name = (null)}##1
++++++++++<NSThread: 0x600000978b00>{number = 8, name = (null)}##1
----------<NSThread: 0x600000978740>{number = 9, name = (null)}##2
++++++++++<NSThread: 0x600000978740>{number = 9, name = (null)}##2
卖出去了一张票,还剩下6张票
----------<NSThread: 0x60000097a880>{number = 10, name = (null)}##3
++++++++++<NSThread: 0x60000097a880>{number = 10, name = (null)}##3
卖出去了一张票,还剩下6张票
----------<NSThread: 0x60000097b940>{number = 11, name = (null)}##4
++++++++++<NSThread: 0x60000097b940>{number = 11, name = (null)}##4
----------<NSThread: 0x60000097b9c0>{number = 13, name = (null)}##6
++++++++++<NSThread: 0x60000097b9c0>{number = 13, name = (null)}##6
----------<NSThread: 0x60000097ba00>{number = 14, name = (null)}##7
++++++++++<NSThread: 0x60000097ba00>{number = 14, name = (null)}##7
----------<NSThread: 0x60000097ba80>{number = 16, name = (null)}##9
++++++++++<NSThread: 0x60000097ba80>{number = 16, name = (null)}##9
卖出去了一张票,还剩下5张票
卖出去了一张票,还剩下5张票
卖出去了一张票,还剩下5张票
----------<NSThread: 0x60000097b980>{number = 12, name = (null)}##5
++++++++++<NSThread: 0x60000097b980>{number = 12, name = (null)}##5
卖出去了一张票,还剩下4张票
卖出去了一张票,还剩下5张票
----------<NSThread: 0x60000097ba40>{number = 15, name = (null)}##8
++++++++++<NSThread: 0x60000097ba40>{number = 15, name = (null)}##8
卖出去了一张票,还剩下4张票
卖出去了一张票,还剩下3张票
网友评论