一、示例代码

import UIKit

let obj = TestObj()

class TestObj {
init() {
print("\(type(of: self)) init")
}
} class ViewController: UIViewController { func test() {
let x = obj
} override func viewDidLoad() {
super.viewDidLoad()
print("ViewController start view didload")
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
for _ in 0...100000 {
DispatchQueue.global().async {
let x = obj
print(x)
}
}
}
}
}

 问题,TestObj 中的初始化方法何时调用?

二、经过测试

  方法在 viewDidLoad 的 log “ViewController start view didload”输出5s之后才会调用

  因为swift中static修饰的全局变量或者类变量都是lazy load,也就是第一次使用的时候才会初始化,并且这个初始化过程是原子化的 

三、多线程安全分析 

  结论: 

    对于只读的全局变量,在多线程环境下面读是安全的;

    对于可变的全局变量,多线程下面写是不安全的,可能造成引用计数不正确,错误释放。

    具体可参考:

    https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html

  为什么只读的情况下面多线程访问是安全的,可以看下面的方法

  

这个方法的反汇编(DEBUG模式下面,编译器优化之后可能有变化)

int _$s14GlobalVarTest214ViewControllerC4testyyF() {
rax = GlobalVarTest2.obj.unsafeMutableAddressor : GlobalVarTest2.TestObj();
rax = *rax;
var_18 = rax;
swift_retain(rax);
rax = swift_release(var_18);
return rax;
}

可以看到全局变量在这个作用域内是先进行了retain操作,最后进行了release。

对一个对象的retain和release操作,本身这个方法是原子操作的,所以不用担心这两个方法的线程安全问题。

如果是全局可写的变量,当两个线程对这个对象进行改变的时候

retain和release中间会出现穿插,导致业务上引用计数的变化不再安全。

因此,对于全局变量写操作,必须进行加锁,保证retain和release在正确的逻辑中。

  

Swift全局变量的线程安全分析的更多相关文章

  1. Spring中获取request的几种方法,及其线程安全性分析

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  2. [No000016E]Spring 中获取 request 的几种方法,及其线程安全性分析

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  3. Spring中获取request的几种方法,及其线程安全性分析(山东数漫江湖)

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  4. Spring中如何获取request的方法汇总及其线程安全性分析

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性.下面话不多说了,来一起看看详细的介绍吧. 概述 在使用Spring MVC开发Web系统 ...

  5. Java线程问题分析定位

    Java线程问题分析定位 分析步骤: 1.使用top命令查看系统资源占用情况,发现Java进程占用大量CPU资源,PID为11572: 2.显示进程详细列表命令:ps -mp 11572 -o THR ...

  6. 李洪强iOS开发Swift篇---12_NSThread线程相关简单说明

    李洪强iOS开发Swift篇---12_NSThread线程相关简单说明 一 说明 1)关于多线程部分的理论知识和OC实现,在之前的博文中已经写明,所以这里不再说明. 2)该文仅仅简单讲解NSThre ...

  7. Android系统--输入系统(七)Reader_Dispatcher线程启动分析

    Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...

  8. Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件

    Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件 1. 输入按键 我们知道Android系统的按键分为三类:(1)Global Key;(2)Syste ...

  9. Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理

    Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理 1. 回顾 我们知道Android输入系统是Reader线程通过驱动程序得到上报的输入事件,还要经过处理 ...

  10. 【转】java线上程序排错经验2 - 线程堆栈分析

    前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...

随机推荐

  1. CentOS 8 安装 oracle 23c CentOS9 Error deal

    1.环境准备 软件准备 序号 软件 下载地址 1 VirtualBox https://www.virtualbox.org/wiki/Downloads 2 CentOS Stream 8 http ...

  2. 报表输入页码翻页(润乾 V2018)

    报表数据分了太多页,一页一页翻页查看数据嫌麻烦,可以试试这种翻页效果--输入页码翻页. 润乾报表提供了翻页相关的 JS 函数,可以在报表展现的页面中添加 JS 调用翻页函数实现输入页码跳转到对应页. ...

  3. 重学c#系列—— 简单编写一个guid [娱乐篇]

    前言 什么是guid? 全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符.GUID主要用于在拥有多个节点.多台计算机的 ...

  4. locust常用的配置参数【locust版本:V1.1.1】

    locust 官网文档地址:https://docs.locust.io/en/stable/configuration.html Locust QQ 群: 执行命令如: master: locust ...

  5. redis cluster 的核心原理分析:gossip 通信、jedis smart 定位、主备切换

    节点间的内部通信机制 基础通信原理 redis cluster 节点间采取 gossip 协议进行通信 gossip:互相之间不断通信,保持整个集群所有节点的数据是完整的 而集中式是将集群元数据(节点 ...

  6. golang开发 深入理解 context

    context的历史 context包在Go 1.7版本正式加入Go标准库.在加入之前我们看看Go团队核心成员Sameer Ajmani在2014年发表的一篇关于context介绍博客,地址:http ...

  7. Oracle 在PL/SQL将字符串分割输出

    Oracle 在PL/SQL将字符串分割输出 示例如下: declare begin for maina in (select tt.line ll from (select regexp_subst ...

  8. 力扣592(java)-分数加减运算(中等)

    题目: 给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即最简分数. 如果最终结果是一个整数,例如 2,你需要将它转换成分 ...

  9. EMT4J——让 Java 应用升级更轻松

    简介: EMT4J 是什么?如何使用 EMT4J 工具进行 Java 应用升级? 前言 JDK 升级对于 Java 应用来说是不得不面对的事情,一方面 Java 生态系统希望 Java 应用能跟上最新 ...

  10. 从 RxJS 到 Flink:如何处理数据流?

    简介: 前端开发的本质是什么?响应式编程相对于 MVVM 或者 Redux 有什么优点?响应式编程的思想是否可以应用到后端开发中?本文以一个新闻网站为例,阐述在前端开发中如何使用响应式编程思想:再以计 ...