游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

字节面试6连问讲讲ThreadLocal与Handler

  作者:冬日毛毛雨
  https:juejin。cnpost7160681836291555365一问:讲讲ThreadLocal和Handler的关系
  竟然提到了Handler机制就不得不提到这几大将了:Handler,Looper,MessageQueue,Message。延伸重点ThreadLocal!!
  当UI的主线程在初始化第一个Handler时,就会通过ThreadLocal创建一个Looper,该Looper与UI主线程一一对应。而使用ThreadLocal的目的是保证每一个线程只创建唯一一个Looper。Looper初始化的时候会创建一个消息队列MessageQueue。至此,主线程、消息循环、消息队列之间的关系是1:1:1。
  Handler、Looper、MessageQueue的初始化流程如下图所示:Hander持有对UI主线程消息队列MessageQueue和消息循环Looper的引用子线程可以通过Handler将消息发送到UI线程的消息队列MessageQueue中。
  二问:主线程为啥不用初始化Looper呢?
  因为Looper早在ActivityThread初始化的时候就声明好了,可以直接拿来用。通过分析源码我们知道MessageQueue在Looper中,Looper初始化后作为对象丢给了Handler,并且又存在了ThreadLocal里面,ThreadLocal和Looper作为k,v存在了ThreadLocalMap,ThreadLocalMap属于当前Thread,也就是说Looper作为桥梁连接了Handler与Looper所在的线程。
  可以理解为Looper关联了Handler和当前线程三问:Handler机制有了解过没?跟我说说?
  在理解Handler机制前,我们需要先搞懂ThreadLocal。
  ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
  想搞懂原理那就得先从源码入手开始分析。我们先从set方法看起:
  从上面的代码不难看出,ThreadLocalset赋值的时候首先会获取当前线程thread,并获取thread线程中的ThreadLocalMap属性。如果map中属性不为空,则直接更新value值,如果map中找不到此ThreadLocal对象,则在threadLocalMap创建一个,并将value值初始化。显然ThreadLocal对象存的值是根据线程走的!
  那么ThreadLocalMap又是什么呢,还有createMap又是怎么做的:
  每个Thread有一个属性,类型是ThreadLocalMap,从代码不难看出ThreadLocalMap是ThreadLocal的内部静态类。它是与线程所绑定联系在一起的,可以看成一个线程只有一个ThreadLocalMap。
  ThreadLocalMap的构成主要是用Entry来保存数据,而且还是继承的弱引用。在Entry内部使用ThreadLocal对象作为key,使用我们设置的对象作为value。
  get比较简单,就是获取当前线程的ThreadLocalMap属性值,在获取Map中对应ThreadLocal对象的value并返回。
  对ThreadLocal做一个总结:每个线程Thread自身有一个属性ThreadLocalMap,这是一个键值对,它的key是ThreadLocal对象,value是我们想要保存处理的数据值。getMap是找到对应线程的ThreadLocalMap属性值,然后通过判断可以初始化或者更新数值。
  ThreadLocal分析完了我们接着来看Handler。
  因为主线程在ActivityThread的main方法中已经创建了Looper,所以主线程使用Handler时可以直接new;子线程使用Handler时需要调用Looper的prepare和loop方法才能进行使用,否则会抛出异常。所以我们从Looper的prepare来分析。
  Looper提供了Looper。prepare()方法来创建Looper,并且会借助ThreadLocal来实现与当前线程的绑定功能。Looper。loop()则会开始不断尝试从MessageQueue中获取Message,并分发给对应的Handler,也就是说Handler跟线程的关联是靠Looper来实现的。
  Looper。loop()负责对消息的分发,也是和prepare配套使用的方法,两者缺一不可。
  msg。target是个啥呢,我们追到Message里面不难发现其实它就是我们发送消息的Handler,这写法是不是很聪明,当从MessageQueen中捞出Message后,我们就能直接调用Handler的dispatchMessage,然后就会走到我们的Handler的handleMessage了。直接上源码:
  Handler提供了一些列的方法让我们来发送消息,如send()系列post()系列。不过不管我们调用什么方法,最终都会走到MessageQueue的enqueueMessage(Message,long)方法。也就是将Message插入到我们的MessageQueue中。
  dispatchMessage()方法针对Runnable的方法做了特殊处理,如果msg。callback!null则会直接执行Runnablerun()
  MessageQueue是个单链表。MessageQueue里消息按时间排序。MessageQueue的next()是个堵塞方法
  总结分析:Looper。loop()是个死循环,会不断调用MessageQueue。next()获取Message,并调用msg。target。dispatchMessage(msg)回到了Handler来分发消息,以此来完成消息的回调。四问:Handler什么会出现内存泄漏问题呢?
  Handler使用是用来进行线程间通信的,所以新开启的线程是会持有Handler引用的,如果在Activity等中创建Handler,并且是非静态内部类的形式,就有可能造成内存泄漏。
  非静态内部类是会隐式持有外部类的引用,所以当其他线程持有了该Handler,线程没有被销毁,则意味着Activity会一直被Handler持有引用而无法导致回收。
  MessageQueue中如果存在未处理完的Message,Message的target也是对Activity等的持有引用,也会造成内存泄漏。
  解决办法:使用静态内部类弱引用的方式:静态内部类不会持有外部类的的引用,当需要引用外部类相关操作时,可以通过弱引用还获取到外部类相关操作,弱引用是不会造成对象该回收回收不掉的问题,不清楚的可以查阅JAVA的几种引用方式的详细说明。
  在外部类对象被销毁时,将MessageQueue中的消息清空。五问:Looper死循环为什么不会导致应用卡死?
  对于线程即是一段可执行的代码,当可执行代码执行完成后,线程生命周期便该终止了,线程退出。而对于主线程,我们是绝不希望会被运行一段时间,自己就退出,那么如何保证能一直存活呢?简单做法就是可执行代码是能一直执行下去的,死循环便能保证不会被退出,例如,binder线程也是采用死循环的方法,通过循环方式不同与Binder驱动进行读写操作,当然并非简单地死循环,无消息时会休眠。
  但这里可能又引发了另一个问题,既然是死循环又如何去处理其他事务呢?通过创建新线程的方式。真正会卡死主线程的操作是在回调方法onCreateonStartonResume等操作时间过长,会导致掉帧,甚至发生ANR,looper。loop本身不会导致应用卡死。六问:主线程的死循环一直运行是不是特别消耗CPU资源呢?
  其实不然,这里就涉及到Linuxpipeepoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在Loop的queue。next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。
  这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步IO,即读写是阻塞的。所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。
  好了,这轮面试中问道的Handler就问了这么多了,大家可以好好的吸收一下

徐小明周二操作策略昨天说的最后一句话是在趋势没有改变的前提下,周二中午是没有这个定点的。定区域空间已经到达了顶部区域,时间上本周也进入到末期了,也属于时间的顶部区域,但定点是需要结构和序列……2024年以后出生的孩子会免费至大学吗?好消息!2024年以后出生的孩子将会免除学费直至大学毕业!这是人大代表赵冬苓为降低育儿成本提出的建议。近几年我国新生人口逐年下降,上学难也是原因之一。幼儿园贵,小学要托管……性暗示这颗毒瘤,正在幼儿圈疯狂生长,家长却谈性色变!前言:中国教育更为含蓄、内敛、传统。因此,在我们面对性这个字眼时,大多数人都会避之不及。甚至谈性色变。可是现在软色情文化盛行,在我们逃避问题时,各种成人性暗示的物品,竟悄……吊带里面怎么穿,最好用的胸贴抹胸全给你总结在这了,速看大解放胸贴10年。你确实它这是胸贴,它不是胶水。作为一个一字肩吊带大户,小v领的s忠粉。关于里面怎么穿胸贴,不管你是想大胸显小胸显丰满。今天这一期都能满足你独家私藏款。1……中国式喂饭会让孩子的脾胃越来越弱,宝宝求你手下留情孩子处于婴幼儿期的时候,因为不具备自主饮食的能力,或是还没有养成良好的饮食意识,这时候家长往往就需要喂孩子吃饭了。这本是无可厚非的事情,但是,如果家长采用了错误的方法来喂……武功山,让人无法拒绝的风景得天独厚的高山云海、壮阔的万亩草甸、绝美的日出日落、漫天的繁星一步一步的行走,用脚步丈量山脊,是打开武功山的最好方式。没走过武功山,都不好意思说自己是户外发烧友。作为华东……科比领衔,从拉塞尔手中获颁过FMVP奖杯的6大球星在2009年2月14日,在凤凰城举办的NBA全明星周末,NBA总裁大卫斯特恩宣布,NBA总决赛的最有价值球员奖正式更名为BillRussellNBAFinalsMostValu……运动会广播稿150字范文运动会广播稿150字范文(一):征服自我对于那些在运动会上拼搏的运动员们来讲,赛场上的胜利输赢不过是一种磨练。真正体现自我只能是超越自我,征服自我。面对紧张的比赛,……县食品安全监管工作情况的调研报告按照州政协20xx年工作安排意见,州政协组成由李永义副主席任组长,州政协办公室、科教文卫体委员会部分委员和州食品安全委员会部分成员单位参加的调研组,于20xx年12月15日至2……责任胜于能力培训心得体会3篇ldquo;责任重于泰山rdquo;,这是我们经常讲的一句话。每一个能够成功发展的优秀企业都非常强调责任的力量。下面是品学网带来的责任胜于能力培训心得,欢迎大家阅读。篇一……大学生驻村工作总结大学生驻村是为基层建设出谋划策的重要途径,也是基层工作改良和发展的重要举措,下面是品学网小编精心整理的大学生驻村工作总结,供大家学习和参阅。大学生驻村工作总结时间过……把握未来预备党员转正思想汇报敬爱的党组织:不知不觉中,20xx年已经过去,回首过去的一年,感觉竟然有些无所事事,觉得自己有些虚度年华的味道,过去了就过去了,感叹已经无用,把握好来年才是关键。这……
教你7招,在外不受欺负,收藏起来,每天读十遍!人性商战,一针见血!1。hr气势不能弱很多时候,别人对你使坏,其实只是为了试探你的底线。所以第一次欺负你的时候,就要反击。做人要有骨气,害人之心不可有,但我们也不能……仅仅助攻不如獭兔,为何绿凯还要拿布朗当交易筹码?数据会骗人的今年季后赛,塔图姆场均21。5分6。8板7助3。8失误,投篮命中率36。7,布朗23。5分7。3板3。6助2。7失误,投篮命中率为43。1,仅仅助攻不如獭兔,为何绿凯还要拿布朗……95后新生代妈妈育儿精细化科学化来源:【中国青年网】中国青年报客户端讯(中青报中青网记者宋宝颖)随着95后逐渐步入适婚、育龄阶段,以她们为代表的新生代妈妈,在育儿、平衡自我发展与家庭等方面观念与前人不同……郭碧婷生了?向佐穿休闲装拿坐月子靠垫好贴心,向太终于圆金孙梦郭碧婷可以说是不折不扣的人生大赢家,成功嫁入豪门之后,婆婆向太一直都对她宠爱有加,当成闺女在宠,跟向佐结婚没几年,就要迎来儿女双全的生活,可以说是非常让人羡慕,而向太也是早早发……小湖有感最近日子总是在忙忙碌碌中度过,甚至一天也见不到外面的喧嚣。生活也变得格格不入了,有种两耳不闻窗外事,一心只在工作中的感觉了。忙着手中的工作,也不曾觉得周末的美好时光了。可是凡事……弘扬长城精神传承爱国情怀探访娘子关下民俗村长城脚下话振兴素有万里长城第九关之称的娘子关,自古就是兵家必争之地。娘子关景区供图中新网太原12月28日电题:探访娘子关下民俗村长城脚下话振兴作者刘小红素有万里长城第九关之……阔腿裤已经不兴了,今年流行用这3款裤配T恤,时髦又显高阔腿裤作为近几年最火单品,基本上每个仙女的衣柜里都会有一条,显瘦显高,颜值和实用性都兼得,但是那么多人穿,阔腿裤几乎满大街都是,如今阔腿裤已经不兴了,今年流行用这3款裤配T恤,……美食推荐荔枝炒虾球泡豇豆鲫鱼野生菌炒五花肉制作方法荔枝炒虾球食材:荔枝、虾仁、蒜末、青椒、胡萝卜、生姜、胡椒粉、盐、鸡精、淀粉、食用油。做法:1、把虾仁去壳,然后开背,去掉虾线,清洗干净,沥干水分备用;……春季养肝,逍遥丸柴胡舒肝丸越鞠丸哪个好?中医看舌象就知道春天得养肝,但养肝药那么多,要是选错了,可不行!因为肝属木,所以基本每个人都知道,春天适合养肝,但世面上的养肝药多了去了,就比如出名的逍遥丸,柴胡舒肝丸,还有越鞠丸等等,……海南风情(054)曲径通幽别有洞天原创党凤山居住在海南陵水红磡香水湾公寓的居民,步行百八十米便来到海边游园。沿着林荫小道进入游园,甬路弯弯曲曲,千转百回,景观各异。这里是椰林,那里是草坪,既有花海,也有池……出行行业第一大应用日活用户达到1000。7万,力压滴滴嘀嗒T根据《2022年第三季度移动互联网行业数据研究报告》显示,哈啰DAU(日活跃用户数量)突破千万,达到1000。7万。超越滴滴出行(961。4万)成为国内出行行业第一大应用,嘀嗒……日本餐厅一些点酒的小知识日本餐厅一些点酒的小知识随着中国去日本旅行和国内日餐的流行,一些朋友常遇到餐厅点酒的问题。通常日本餐厅除了日本清酒、啤酒等之外,还有三种比较流行的日本酒水:、(酎)、。……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网