美文网首页
java中的ThreadLocal

java中的ThreadLocal

作者: 初心myp | 来源:发表于2019-07-31 09:29 被阅读0次

ThreadLocal是一个关于创建线程局部变量的类。
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。

Global && Local

上面的两个修饰看似矛盾,实则不然。

  • Global 意思是在当前线程中,任何一个点都可以访问到ThreadLocal的值。
  • Local 意思是该线程的ThreadLocal只能被该线程访问,一般情况下其他线程访问不到。

用法简介

创建,支持泛型
ThreadLocal<String> mStringThreadLocal = new ThreadLocal<>();
//set方法
mStringThreadLocal.set("droidyue.com");
//get方法
mStringThreadLocal.get();
完整的使用示例:
private void testThreadLocal() {    
    Thread t = new Thread() {        
        ThreadLocal<String> mStringThreadLocal = new ThreadLocal<>();        

        @Override        
        public void run() {           
            super.run();            
            mStringThreadLocal.set("droidyue.com");            
            mStringThreadLocal.get();       
        }    
    };    
    t.start();
}
ThreadLocal初始值

为ThreadLocal设置默认的get初始值,需要重写initialValue方法,下面是一段代码,我们将默认值修改成了线程的名字

ThreadLocal<String> mThreadLocal = new ThreadLocal<String>() {    
    @Override    
    protected String initialValue() {      
        return Thread.currentThread().getName();    
    }
};
如何实现

为了更好的掌握ThreadLocal,我认为了解其内部实现是很有必要的,这里我们以set方法从起始看一看ThreadLocal的实现原理。
下面是ThreadLocal的set方法,大致意思为

  • 首先获取当前线程
  • 利用当前线程作为句柄获取一个ThreadLocalMap的对象
  • 如果上述ThreadLocalMap对象不为空,则设置值,否则创建这个ThreadLocalMap对象并设置值

源码如下

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);}

下面是一个利用Thread对象作为句柄获取ThreadLocalMap对象的代码

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

上面的代码获取的实际上是Thread对象的threadLocals变量,可参考下面代码

class Thread implements Runnable {
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;
}

而如果一开始设置,即ThreadLocalMap对象未创建,则新建ThreadLocalMap对象,并设置初始值。

void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

总结:实际上ThreadLocal的值是放入了当前线程的一个ThreadLocalMap实例中,所以只能在本线程中访问,其他线程无法访问。

相关文章

网友评论

      本文标题:java中的ThreadLocal

      本文链接:https://www.haomeiwen.com/subject/rqnnrctx.html