【内核研究】线程局部存储_TheadLocal

来源:互联网 发布:java 2d游戏引擎 编辑:程序博客网 时间:2024/06/15 18:04

通过调用Looper的静态方法prepare()为线程创建MessageQueue对象,代码如下:

    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));    }
变量sThreadLocal的类型是ThreadLocal,该类的作用是提供“线程局部存储”,那么什么是线程局部存储呢?可以从变量作用域的角度去理解。

常见的变量作用域一般包括以下几种。

  • 函数内部的变量。其作用域是该函数,每次调用该函数,变量都会被重新初始化。
  • 类内部的变量。其作用域是该类的对象,即只要该对象没有被销毁,对象内的变量就保持不变。
  • 类内部的静态变量。其作用域是整个进程,即只要在该进程中,则该变量的值就一直保持,无论使用该类创建了多少个对象,该变量只有一个值,并一直保持。

线程局部存储:从一个线程中引用该变量,其值总是相同的;而从不同的线程中引用该变量,其值总是不同的。总之,它是一种作用域为线程的变量。

再看Looper.java的prepare()方法。

     /** Initialize the current thread as a looper.      * This gives you a chance to create handlers that then reference      * this looper, before actually starting the loop. Be sure to call      * {@link #loop()} after calling this method, and end it by calling      * {@link #quit()}.      */    public static void prepare() {        prepare(true);    }
这是一个静态方法,其内部会转发到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));    }
注意这句代码:
 sThreadLocal.set(new Looper(quitAllowed));
sThreadLocal通过调用set()方法,将一个新的Looper对象和调用它的线程绑定在了一起。

接下来看myLooper()方法,代码如下:

    /**     * Return the Looper object associated with the current thread.  Returns     * null if the calling thread is not associated with a Looper.     */    public static Looper myLooper() {        return sThreadLocal.get();    }
这也是一个静态方法,通过sTreadLocal的get()方法,获得与调用它的线程所绑定的Looper对象。


总结,不同类型变量的作用域。变量作用域类型意义函数成员变量仅在函数内部有效类成员变量仅在对象内部有效线程局部存储(TLS)变量在本线程内的任何对象内保持一致静态变量在本进程内的任何对象内保持一致夸进程通信(IPC)变量一般使用Binder进行定义,在所有进程内保持一致。


0 0
原创粉丝点击