IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 多线程四部曲之NSThread -> 正文阅读

[移动开发]多线程四部曲之NSThread

NSThread是什么?

众所周知在iOS多线程开发主要有四种方式,NSThread就是其中一种。
在这里插入图片描述
下面是apple官方给出的解释
在这里插入图片描述
可以看出NSThread是apple封装的一个线程类,开发人员可以对线程进行操作,并且可以监控线程状态。
NSThread是基于线程使用,轻量级的多线程编程方法(相对GCDNSOperation),一个NSThread对象代表一个线程

NSThread的使用

NSThread的创建

该类的创建方法比较简单,大致可以分为动态和静态两种方法。

  • 1.可以动态创建(实例方法)初始化NSThread对象,需要自己调用- (void)start方法启动线程。
// 参数意义
/*target
selector指定的消息发送到的对象。
selector
要发送消息到target的选择器。此选择器必须只接受一个参数,并且不得具有返回值。
argument
传递给目标的单个参数。可能是nil。
*/
 NSThread *firstThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
    firstThread.name = @"thread1";
    [firstThread start];
  • 2.也可以通过NSThread的静态方法(类方法)快速创建并自动启动新线程
// 分离新线程,并使用指定的选择器作为线程入口点。

    [NSThread detachNewThreadSelector:@selector(pressBack:) toTarget:self withObject:@"thread4"];
  • 3.此外NSObject基类对象还提供了隐式快速创建performSelector,自动启动新线程
[self performSelectorInBackground:@selector(threadRun) withObject:@"thread5"];

一些线程通信

 // 当前线程执行操作
//    [self performSelector:@selector(threadRun)];
//    [self performSelector:@selector(threadRun) withObject:@"thread6"];
//    // 延迟n秒后进入线程
//    [self performSelector:@selector(threadRun) withObject:@"thread7" afterDelay:2.0];
//    // 在其他线程中指定主线程操作
//    [self performSelectorOnMainThread:@selector(threadRun) withObject:nil
//    waitUntilDone:YES];
//     // (在主线程中)指定其他线程执行操作
//    [self performSelector:@selector(threadRun) onThread:thread1
//    withObject:nil waitUntilDone:YES];
// 	  wait为YES需要等待主线程操作,NO子线程无需等待
//     //这里指定为某个线程
//     [self performSelectorInBackground:@selector(threadRun) withObject:nil];
     //这里指定为后台线程

NSThread的一些属性

在这里插入图片描述

简单例子,售票处理

假设我们需要卖一百张电影票,我们在售票处同时开了三个窗口售票

{
// 线程同步问题:
    NSThread *firstThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
    firstThread.name = @"thread1";
    NSThread *secondThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
    secondThread.name = @"thread2";
    NSThread *thirdThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
    thirdThread.name=@"thread3";
    [firstThread start];
    [secondThread start];
    [thirdThread start];
    [NSThread currentThread];
//    while(1) {
//        NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
//        [thread start];
//    }
}
- (void)sellTicket:(NSThread*) thread {
    while (self.ticketsCount > 0) {
        NSThread *thread = [NSThread currentThread];// 获取当前线程
        [NSThread sleepForTimeInterval:2];
        self.ticketsCount -- ;
        NSLog(@"当前线程:%@\n剩余票数为:%d ",thread.name, self.ticketsCount);
   }
}

看一下运行结果,发现数据会混乱,这是因为我们没有实现线程同步,造成了资源竞争。
在这里插入图片描述
下面我们可以实现线程同步:

  1. 第一种方式@synchronized(对象)关键字也就是互斥锁,在新的线程访问时,如果发现其他线程正在执行锁定的代码,新线程进入休眠.
- (void)sellTicket:(NSThread*) thread {
    while (self.ticketsCount > 0) {
        @synchronized(self) {
        NSThread *thread = [NSThread currentThread];
        [NSThread sleepForTimeInterval:2];
        self.ticketsCount -- ;
        NSLog(@"当前线程:%@\n剩余票数为:%d ",thread.name, self.ticketsCount);
        }
    }
}
  1. 还可以使用NSLock
    NSLock 是 Cocoa 提供给我们最基本的锁对象,也是经常使用的,除 lock 和 unlock 方法外,NSLock 还提供了 tryLock 和 lockBeforeDate: 两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),并不会阻塞线程,直接返回 NO。lockBeforeDate: 方法会在所指定 Date 之前尝试加锁,如果在指定时间之前都不能加锁,则返回 NO。
self.threadLock = [[NSLock alloc]init];
while (self.ticketsCount > 0) {
        [self.threadLock lock];
        //[self.condition lock];
        NSThread *thread = [NSThread currentThread];
        [NSThread sleepForTimeInterval:2];
        self.ticketsCount -- ;
        NSLog(@"当前线程:%@\n剩余票数为:%zd ",thread.name, self.ticketsCount);
        [self.threadLock unlock];
        //[self.condition unlock];
    }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:45:08  更:2022-06-14 22:46:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:40:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码