Looper对象为什么要通过ThreadLocal来保存?

我们看看Looper.prepare()方法:

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

    public static void prepare() {
    
    
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
    
    
        if (sThreadLocal.get() != null) {
    
    
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

Looper对象为什么要通过ThreadLocal来保存?

Looper在设计之初,就希望一个线程只有一个Looper和一个MessageQueue,共同处理发送给自己的Message。其他线程有其他线程的Looper和MessageQueue。这其实是线程隔离。Thread+ThreadLocal+ThreadLocalMap是JDK提供的一种实现线程隔离的方式(具体怎么实现的,看我的这篇:ThreadLocal是如何实现线程隔离的?)。开发者也可以用别的方式实现线程隔离。ThreadLocal的使用方式,就是通过set()方法,将需要隔离的数据存放在ThreadLocalMap里面。

结论:Looper对象,通过ThreadLocal来保存,是线程隔离的实现方式,最终达到一个线程只有一个Looper的目的。Thread+ThreadLocal+ThreadLocalMap是JDK提供的一种实现线程隔离的方式。开发者也可以用别的方式实现线程隔离。

有些博客讲,looper对象通过ThreadLocal存储是为了线程安全,个人认为这里并没有什么安不安全的问题,每个线程都有自己的Looper,线程不会去使用和修改别的线程的Looper,没有必要也没有意义。两个线程需要通信的时候,就用Handler消息机制就好了。

猜你喜欢

转载自blog.csdn.net/zhangjin1120/article/details/131469646