主线程死锁是 Android 开发中常见的问题之一,通常发生在 UI 线程被阻塞,导致应用卡住无法响应用户操作。这样的情况如果不及时解决,可能会严重影响用户体验和应用的稳定性。下面将详细记录我们在解决 Android 主线程死锁的过程,包括业务影响分析、错误现象、根因分析、解决方案、验证测试和预防优化。
#### 问题背景
在某项目中,一次代码更新致使用户在打开某个功能时频繁遇到界面无响应的情            
                
         
            
            
            
            先看一个售票案例Demo,多线程程序对共享数据操作引发的安全问题:package android.java.thread09;
/**
 * 售票线程
 */
class Booking implements Runnable {
    /**
     * 模拟票的总算 10张票
     */
    private int ticket = 10;
    @Override            
                
         
            
            
            
            一、主线程    (1)主线程的定义:            在iOS操作系统中,一个程序运行后,默认会开启一个线程,称为“主线程”或“UI线程”。    (2)主线程的作用:              
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-10-25 17:13:40
                            
                                182阅读
                            
                                                                                    
                                1评论
                            
                                                 
                 
                
                                
                     
                                    
                             
         
            
            
            
            1.多线程的底层实现(1)首先回答什么是线程1个进程要想执行任务,必须得有线程.线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行(2)什么是多线程1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务。多线程的作用:更新显示UI界面、处理用户触摸事件。(3)Mach是第一个以多线程方式处理任务的系统,因此多线程的底层实现机制是基于Mach的线程。(4)开发中实现多线程            
                
         
            
            
            
            在iOS开发中,主线程死锁是一种常见且令人头痛的问题,它会导致应用程序的无响应,严重影响用户体验。本文将详细分析iOS主线程死锁的背景、错误现象、根因、解决方案、验证测试及预防措施,帮助开发者更好地理解与解决这一问题。
***
### 问题背景
在某个大型电商应用中,我们发现用户在结账时,应用的主线程出现了死锁,导致界面完全无响应。这种情况影响了用户下单的意愿,进而影响了整体的销售业务。经分            
                
         
            
            
            
            关于什么是线程,计算机系统的任务发展史,咱这里就不说了。说点比较有意思的东西。附加:安卓里面的线程: 1.创建线程使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。 (方法一)Thread构造函数: public Thread( );            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-11-13 21:12:30
                            
                                106阅读
                            
                                                                             
                 
                
                                
                     
                                    
                             
         
            
            
            
              上一篇文章我对GCD的几个基本概念做了介绍,但是大家看完了可能觉得对理解GCD并没有什么卵用。其实会用GCD其实很简单,只要记住两条就可以了。1. 主队列里的任务必须在异步函数中执行。  主队列里的任务如果在同步函数中执行,就会造成死锁。什么是死锁?容我举例来说明。 代码- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-10-02 20:48:08
                            
                                91阅读
                            
                                                                             
                 
                
                                
                     
                                    
                             
         
            
            
            
            在使用dispatch_sync时,一定要防止deadlock发生。 
如下: - (void)viewDidLoad
{
   [superviewDidLoad];
   
   dispatch_queue_tqueue1 = dispatch_get_main_queue();
   dispatch_sync(queue1,^{NSLog(@"222 Hello?");});
   
             
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-09-13 18:00:39
                            
                                103阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            俗话说“书卷多情似故人,晨昏忧乐每相亲”闲暇之时,我们还是要多和故人联络联络感情。哈哈,言归正传,安闲之余,看操作系统原理一书,里面有一章节讲解的是死锁,很多人认为,死锁是很高端的操作系统层面的问题,离我们很远,一般不会遇上。其实这种想法是非常错误的,作为一名iOS开发,在iOS中,下面这段常见的程序就会造成死锁:int main(int argc, const char * argv[]) {            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-07-21 18:32:18
                            
                                136阅读
                            
                                                                             
                 
                
                                
                     
                                    
                             
         
            
            
            
            # 如何实现 iOS 主线程队列死锁的示例
死锁是多线程编程中常见的问题,理解它的工作原理有助于开发人员更好地编写出高效且安全的代码。本文将指导你如何在 iOS 中实现一个主线程队列死锁的示例,并解释每一个步骤的流程及代码实现。
## 步骤流程
| 步骤          | 描述                                 | 操作            
                
                    
                        
                                                            
                                                                        
                                                                                        原创
                                                                                    
                            2024-10-31 11:27:20
                            
                                75阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            今天博主有一个多线程开发的需求,遇到了一些困难点,在此和大家分享,希望能够共同进步. 在iOS开发中,多线程开发是非常重要的核心之一,这篇文章和大家分享一下多线程的进阶-死锁.iOS有三种多线程编程的技术,分别是:(一)NSThread(二)Cocoa NSOperation(三)GCD(全称:Grand Central Dispatch)如果你对多线程开发还没有基本的了解,建议你看下面            
                
         
            
            
            
            # iOS 主线程死锁的原因及解决方案
在 iOS 开发中,主线程是一个非常关键的概念。主线程负责处理用户界面(UI)更新和用户交互。当我们在主线程上执行耗时的操作时,应用程序可能会表现出卡顿,甚至死锁的情况。这篇文章将探讨主线程死锁的原因,提供代码示例,并给出一些预防和解决的方法。
## 什么是主线程死锁?
主线程死锁是指在主线程中,代码的执行因等待某个条件而导致无法继续执行,从而形成一种            
                
         
            
            
            
            前言:1.对Thread.sleep(long duration)的认知。        由于CPU分配的每个线程的时间片极为短暂(一般为几十毫秒),所以,CPU通过不停地切换线程执行,这样就给程序员一种错觉,以为多个线程是在同时执行。sleep就是正在执行的线程主动让出CPU,CPU去执行其他线程,在sleep指定的时间过后,            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-07-06 22:33:23
                            
                                209阅读
                            
                                                                             
                 
                
                                
                     
                                    
                             
         
            
            
            
            什么是线程死锁线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于相互等待状态,若无外力作用,它们将无法继续执行下去。造成死锁的原因可以概括成三句话:当前线程拥有其他线程需要的资源当前线程等待其他线程已拥有的资源都不放弃自己拥有的资源线程死锁产生的四个必要条件互斥,共享资源 X 和 Y 只能被一个线程占用;占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-08-13 16:25:39
                            
                                218阅读
                            
                                                                             
                 
                
                                
                     
                                    
                             
         
            
            
            
            首先 先 明白一个问题:什么是ANRApplication Not Responding,意思是”应用没有响应“以前我的理解就是 “在主线程做了耗时操作”就会引起ANR,现在我觉得我是错误的,ANR的意思是应用没有响应,耗时操作实际上 并不一定会导致没有响应,我对没有响应的理解是有人(事件或操作)发出了一个请求,但是主线程没有对这个人进行反馈(可能是没时间、可能是不想理、可能是手被绑住了没有办法理            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-08-17 15:37:03
                            
                                222阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            结论初始化后,所有主线程做的事情都是在looper.loop()中完成的,因为主线程不做其他事,所以不会卡死基于linux的epoll模型,当主线程没有message消费时,会进入睡眠状态(简单理解),等到有新的可消费的Message时,再转为活跃状态处理Message(类似一个事件回调)。主线程在睡眠状态会让出CPU,并不是一直不停在执行循环。如有兴趣了解下epoll机制可以看看这篇文章:NIO            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-11-08 08:56:17
                            
                                182阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            首先 先 明白一个问题:什么是ANRApplication Not Responding,意思是”应用没有响应“以前我的理解就是 “在主线程做了耗时操作”就会引起ANR,现在我觉得我是错误的,ANR的意思是应用没有响应,耗时操作实际上 并不一定会导致没有响应,我对没有响应的理解是有人(事件或操作)发出了一个请求,但是主线程没有对这个人进行反馈(可能是没时间、可能是不想理、可能是手被绑住了没有办法理            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-08-29 16:58:51
                            
                                303阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。 在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 概念。我们的主线            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-09-02 13:04:36
                            
                                115阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            知乎上看到这样一个问题Android中为什么主线程不会因为Looper.loop()里的死循环卡死?,于是试着对Handler源码重新看了一下,其实Android的消息机制是Pipe+epoll(了解epoll),有消息时则依次执行,没消息时调用epoll.wait等待唤醒;由于Android中生命周期、UI绘制都是动过Handler实现的,因此自然不会发生阻塞卡死。Android为了保证主线程在            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-07-31 23:15:40
                            
                                165阅读
                            
                                                                             
                 
                
                             
         
            
            
            
            首先 先 明白一个问题:什么是ANRApplication Not Responding,意思是”应用没有响应“以前我的理解就是 “在主线程做了耗时操作”就会引起ANR,现在我觉得我是错误的,ANR的意思是应用没有响应,耗时操作实际上 并不一定会导致没有响应,我对没有响应的理解是有人(事件或操作)发出了一个请求,但是主线程没有对这个人进行反馈(可能是没时间、可能是不想理、可能是手被绑住了没有办法理            
                
                    
                        
                                                            
                                                                        
                                                                                        转载
                                                                                    
                            2023-07-31 20:15:33
                            
                                156阅读