1.Handler的工作流程( 六 )


这种基于消息队列和消息循环的机制可以保证消息的顺序和准确性 。较早触发的消息会先被处理 , 而较晚触发的消息会在之后的时刻被处理 , 确保了消息处理的有序性 。同时 , 通过消息队列的排序 , 可以优先处理优先级较高的消息 。
3.的相关知识
先说一下的作用,我们在进行
Looper.prepare();
的时候点击源码进去会发现里面进行了的set方法,
而它的作用在我理解就是在多个线程中虽然调用的是同一个,但是它们的值不一样,根本原因是因为内部有一个
我们看看内部的set方法
3.的set方法
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}
我们会发现的set方法会先获得当前的线程,然后获得,判断map为不为空,如果它不为空,就直接把当前的线程和value值传给map , 如果map为null的话则创建map
这里面我们就可以明白为什么每个的不一样了
因为
Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);
我们会发现它是先获得当前的线程,然后再用获得的线程来创建
创建的话很简单
void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}
就new一个
我们看看内部
3.1.
ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);table[i] = new Entry(firstKey, firstValue);size = 1;setThreshold(INITIAL_CAPACITY);}/*** Construct a new map including all Inheritable ThreadLocals* from given parent map. Called only by createInheritedMap.** @param parentMap the map associated with parent thread.*/private ThreadLocalMap(ThreadLocalMap parentMap) {Entry[] parentTable = parentMap.table;int len = parentTable.length;setThreshold(len);table = new Entry[len];for (int j = 0; j < len; j++) {Entry e = parentTable[j];if (e != null) {@SuppressWarnings("unchecked")ThreadLocal key = (ThreadLocal) e.get();if (key != null) {Object value = http://www.kingceram.com/post/key.childValue(e.value);Entry c = new Entry(key, value);int h = key.threadLocalHashCode & (len - 1);while (table[h] != null)h = nextIndex(h, len);table[h] = c;size++;}}}}
其实别看这么多的代码,我的理解就是就是用一个Entry数组存储 , 并结合了哈希表的概念
为什么这么说呢,因为它是一个二维数组,其中第一个为索引值,第二个为存储对象 。
存储的是什么呢?Entry 的 key 就是线程的本地化对象  , 而 value 则存放了当前线程所操作的变量副本 。
其中最容易被问到的还有就是内存泄漏
我们先了解一下什么是内存泄漏
3.2内存泄漏
在中 , 内存泄漏指的是应用程序在运行过程中 , 由于不正确的内存管理导致一些对象无法被垃圾回收器正确释放 , 从而造成内存资源的浪费和持续占用 。这些未释放的对象会继续占用内存空间 , 导致应用程序的内存占用逐渐增加 , 最终可能导致内存溢出或导致应用程序运行缓慢、卡顿甚至崩溃 。
在中内存泄露的根本原因在于的生命周期与当前线程的生命周期相同 , 且使用完没有进行手动删除导致的
所以我们如果进行**()方法后不进行.()**方法就会导致内存泄漏