多线程四部曲之NSThread

2023-11-15

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];
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程四部曲之NSThread 的相关文章

随机推荐

  • CNI Plugin 介绍

    CNI 插件包括两种类型 CNI Plugin 和 IPAM IP Address Management Plugin CNI Plugin 负责为容器配置网络资源 IPAM Plugin 负责对容器的 IP 地址进行分配和管理 IPAM
  • Mac 下配置 Python3 和 Selenium3 环境

    Selenium 是一套 Web 测试框架 Selenium2 中新增加了 Webdriver 可以用了测试 UI 层 控制浏览器执行爬虫等操作 而 chromedriver 是 Selenium 控制浏览的必要驱动 一 安装 seleni
  • CCP协议

    CCP协议 2021 11 12 标定流程 将标定数据保存在Flash中 在程序初始化过程中 标定数据映射至RAM当中 程序从RAM中调取数据 标定过程开始时 在上位机中建立Flash存储区镜像 并保存至HEX文件 标定过程中 通过DNLO
  • cookie中文乱码问题

    下面是写入cookie的代码 csharp view plain copy Cookie nameCookie new Cookie name 张三 nameCookie setMaxAge 60 60 24 30 response add
  • 多普勒超声波流量计工作原理及优缺点

    多普勒超声波流量计是是利用声波在流体中传播的多普勒效应 通过测定流体中运动粒子散射声波的多普勒频移 即可得到流体的速度 结合内置压力式水位计 利用速度面积法 即可测量液体的流量 适合于明渠 河道及难以建造标准断面的流速流量测量以及于各种满管
  • 河道堤防GNSS位移监测系统

    一 方案背景 我国河系众多 海岸线漫长 在江边 河边 海边修筑修筑着几万公里的提防设施保卫着沿江 沿海居民的生命安全 也保卫着经济发展的累累硕果 近年来 因台风暴雨造成河道堤坝决堤 产生的经济损失越来越大 各对方对防洪堤 海堤的安全检查要求
  • 【数据可视化】利用 Flourish 制作动态排名条形图(无需代码,超简单)

    利用 Flourish 制作动态排名条形图 一 Flourish 介绍 数据可视化不仅是一项技术 也是一门艺术 当然 数据可视化的工具也非常多 仅 Python 就有 matplotlib plotly seaborn bokeh 等多种可
  • ubuntu16.04,如何修改网卡名称为eth0?(转)

    一开始没有注意 输入ifconfig显示的是 ens33 lo 觉得没有影响 就是一个名字的事情 但是百度以后发下 强迫症 具体看知乎大佬的连接 https www zhihu com question 45796677 感谢 流沙 大佬
  • labuladong 公众号的使用方法

    先给大家说句抱歉 前段时间 labuladong 有些事情在忙 所以更新频率比较慢 以后就恢复正常了 自开号以来 labuladong 的算法文章开了 靠套路刷题 的先河 一直被模仿 从未被超越 GitHub 开源 fucking algo
  • Maven 安装和使用详解详解(windows 环境)

    目录 1 maven 安装步骤 1 从 Apache 官网下载 maven 压缩包 2 解压 maven 压缩包 即可使用 3 配置 maven 环境变量 方便全局使用 3 检测是否安装配置成功 2 Maven 使用详解 1 修改 sett
  • IntelliJ IDEA无法运行新建的java类,灰色运行标志【终于找到!!】

    问题 创建新类 但是就是不能运行 运行的按钮都是灰色的 只有下面默认的自带的main函数能够运行 鼠标右键找不到运行函数类似图二 但是这个错误首先请确保自己的JDK没有问题 如图 鼠标右键也找不到运行标志 结果发现 从c 过来的编译习惯 总
  • No2.7 前端面试题 1. token 2. 浏览器页面渲染的过程 3. SVG格式 4. 精灵图和base64

    1 token 什么是token token是验证身份的令牌 一般是用户通过账号密码登录后 服务端把这些凭证通过加密等一系列操作后得到的字符串 token都存在哪里 有什么区别 存localstorage里 后期每次请求接口时都需要把它当做
  • 索尼的hlg是什么_索尼HLG的使用方法

    近几年HLG的出现 让我们普通的摄影爱好者 可以直接的拍摄高动态范围的影像 尤其是小型的团队和独立的视频制作人 HLG能让我们在拍摄完素材够后 稍微调整就可以得到很不错的画面效果 能让我们省去很多后期调色的麻烦 这对于没有调色基础的摄影爱好
  • ABAP DIALOG 读取屏幕字段和tablecontrol内字段

    在POV事件中 因为没有经过PAI直接进入POV中的MODULE 所以直接调用屏幕中的字段并没有值 所以要 用DYNP VALUES READ读取屏幕字段的值 且读取的值格式为输入的格式 当使用DYNP VALUES READ时 所读取的屏
  • VMware vCenter Server远程代码执行漏洞复现 CVE-2021-21972

    文章来源 MS08067安全实验室 本文作者 Taoing WEB高级攻防班讲师 0x00 漏洞描述 CVE 2021 21972 vmware vcenter的一个未任意位置 然后执行webshell即可 0x01 影响版本 VMware
  • PyTorch学习之 torch.optim 的6种优化器及优化算法介绍

    import torch import torch nn functional as F import torch utils data as Data import matplotlib pyplot as plt import nump
  • 产品经理如何收集用户需求和痛点-新做市面上同类产品

    对于市面上已有同类产品 我们要做类似的产品 要使新做出来的产品有竞争力 首先需要深入了解客户需求和痛点 了解用户使用竞品的感受和痛点 在办公室冥想客户需求 并不靠谱 办公室做产品的结果 很多产品到客户那一用 才发现问题很多 很多实际情况没有
  • CiteSpace 的安装与使用 —— 入门

    下载 CiteSpace 是一种可视化的工具 在写论文的时候便于用来筛选对自己写文章有用的论文 CiteSpace 是一款免费的软件 可以直接到官网下载安装 注意 要配置 Java 环境才能使用 安装 下载后直接双击即可 双击打开应用 首先
  • Qt中使用QProcess备份和恢复Mysql数据库

    使用Qt做MySQL数据库开发 遇到需要备份 还原数据库的问题 MySQL中没有提供将数据库备份成 sql文件的SQL语句 而是提供了一个mysqldump exe工具来完成这个功能 没有SQL语句 QSqlQuery就用不成了 决定改用Q
  • 多线程四部曲之NSThread

    NSThread是什么 众所周知在iOS多线程开发主要有四种方式 NSThread就是其中一种 下面是apple官方给出的解释 可以看出NSThread是apple封装的一个线程类 开发人员可以对线程进行操作 并且可以监控线程状态 NSTh