热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:swift5.x多线程的应用场景

本文由编程笔记#小编为大家整理,主要介绍了swift5.x 多线程的应用场景相关的知识,希望对你有一定的参考价值。 //// ViewController17.swift// swiftT////
本文由编程笔记#小编为大家整理,主要介绍了swift5.x 多线程的应用场景相关的知识,希望对你有一定的参考价值。


//
// ViewController17.swift
// swiftT
//
// Created by wjwdive on 2020/6/3.
// Copyright ? 2020 wjwdive. All rights reserved.
//
import UIKit
class ViewController17: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//线程不安全的示例
// noThreadSafeSimple()
//线程安全的示例
ThreadSafeSimple()
//线程安全的 优化读写操作示例
betterThreadSafeArraySimple()
}
}
//多线程的应用场景
//1 一个也没有三个网络请求,需要再三个网络请求返回的时候刷新界面
//2 需要一个线程安全的Array的读写
//3 编写一个多线程下载器,可执行多个下载任务,每个任务可以保存当下下载的字节数,总字节数,可以设置回调得到当前下载进度
//4 需要再主线程等待一个异步任务返回,才能继续执行下面的逻辑,但是又不希望堵塞用户事件。
//1 一个也没有三个网络请求,需要再三个网络请求返回的时候刷新界面
//实现:
// 三个网络请求分别是一个Operation,刷新界面是一个Operation,刷新界面的Operation依赖三个网络请求的Operation。这样就能保证三个网络请求都成功之后才刷新界面。
//2 需要一个线程安全的Array的读写
// 不做线程安全处理出错的示例:
//线程A
//线程B
//1??线程A获取Array的长度length
//2??线程B删除了Array的最后一个元素
//3??线程A根据length 读取Array的最后一个元素,这时就会出错
//线程不安全的示例:
func noThreadSafeSimple() {
//线程不安全的示例
var array = Array(0...10000)
func getLastItem() -> Int? {
var temp: Int? = nil
if array.count > 0 {
temp = array[array.count - 1] //这行代码在获取array长度之后,可能中间有另一个线程在remove元素,之后在取最后一个元素,出现数组越界。
}
return temp
}

func removeLastItem() {
array.removeLast()
}

let queue = DispatchQueue(label:"queue1")
queue.async {
for _ in 0..<10000 {
removeLastItem()
}
}
let queue2 = DispatchQueue(label:"queue2")
queue2.async {
for _ in 0..<10000 {
if let item = getLastItem() {
print(item)
}
}
}

}
//安全的Array示例:
func ThreadSafeSimple() {
//线程安全的示例
var array = Array(0...10000)
let lock = NSLock()//加锁
func getLastItem() -> Int? {
var temp: Int? = nil
lock.lock()
if array.count > 0 {
temp = array[array.count - 1] //这行代码在获取array长度之后,可能中间有另一个线程在remove元素,之后在取最后一个元素,出现数组越界。
}
lock.unlock()//解锁
return temp
}

func removeLastItem() {
lock.lock()
array.removeLast()
lock.unlock()
}

let queue = DispatchQueue(label:"queue1")
queue.async {
for _ in 0..<10000 {
removeLastItem()
}
}
let queue2 = DispatchQueue(label:"queue2")
queue2.async {
for _ in 0..<10000 {
if let item = getLastItem() {
print(item)
}
}
}

}
//如果在一段时间内只有只读操作,我们是不需要加锁的。而上述NSLock的方式仍然强制每次读操作都加锁等待,对性能造成不小的影响,尤其是我们对数组的操作远远多于写操作的时候,这个性能的影响就相当可观,那么该如何优化呢?
//优化:
// 一个队列加两个方法
//1 首先是并行队列,既然我们要保持多线程环境并行操作的优势,那我们肯定要选择并行队列。
//2 二是sync方法,这个方法来封装我们的读操作,读操作的发起方需要在调用读方法的时候能直接拿到返回值,而不是在异步回调里面获取。
//3 三是async方法适用barrier flag, z这个方法来封装我们的鞋操作,这个方法起到一个栅栏的作用,它等待所有位于 barrier async函数之前的操作执行完毕后执行,并且在barrier async函数执行后,barrier async函数之后的操作才会得到执行
func betterThreadSafeArraySimple() {
var array = Array(0...10000)
var cOncurrentQueue= DispatchQueue(label: "concurrent queue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)

func getLastItem() -> Int? {
var temp: Int? = nil
concurrentQueue.sync {
if array.count > 0 {
temp = array[array.count - 1]
}
}
return temp
}

func removeLastItem() {
let workItem = DispatchWorkItem(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
array.removeLast()
}
concurrentQueue.async(execute: workItem)
}
}

推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
author-avatar
mobiledu2502931437
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有