技术文章 > java >  java基础 > 正文

java中ThreadLocal核心方法有哪些?

小妮浅浅

在对于线程安全的讨论上,我们会试图寻找各种方法,锁的用法这里就不再提了,我们今天主要是教大家使用ThreadLocal变量。它可以结合一些方法来对线程进行操作,比如get()方法、remove()方法。下面我们就这两种方法在ThreadLocal中使用分别进行介绍,大家都来看看具体的操作吧。

1、get()方法

(1)获取当前用的线程,并找到线程关联的threadLocalMap

(2)threadLocalMap为空则进行初始化一个新的并返回

(3)threadLocalMap不为空则根据threadlocal作为key查找Entry

(4)若Entry不为空则返回entry对应的值,否则执行第二条

public T get() {
    // 获取当前线程
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    //若当前线程关联的ThreadLocal不为空则查询
    if (map != null) {
        //根据threadLocal查询对应的Entry
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}
 
 private T setInitialValue() {
     //默认返回null值
     T value = initialValue();
     Thread t = Thread.currentThread();
     ThreadLocalMap map = getMap(t);
     //如果当前调用线程关联的ThreadLocalMap为空则创建,否则设置值进去
     if (map != null)
         map.set(this, value);
     else
         //new ThreadLocalMap(this,value)
         createMap(t, value);
     return value;
 }
 
private Entry getEntry(ThreadLocal<?> key) {
    //根据key获取其在数组的下标位置
    int i = key.threadLocalHashCode & (table.length - 1);
    Entry e = table[i];
    if (e != null && e.get() == key)
        return e;
    else
        return getEntryAfterMiss(key, i, e);
}
 
private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
    Entry[] tab = table;
    int len = tab.length;
    //数组下标的Entry不为空且关联的threadlocal与查找的threadlocal不一致
    while (e != null) {
        ThreadLocal<?> k = e.get();
        //entry关联的threadlocal与查找的相等则直接返回
        if (k == key)
            return e;
        if (k == null)
            //关联的threadlocal为空,则触发清理key为null的Entry并重新进行rehash旧Entry数组的元素
            //threadLocalMap的hash冲突与hashMap的冲突处理方式不一致,hashMap使用的是链表地址法,
            //而threadLocalMap使用的开放地址法——线性探测,即顺序查找下一位置或者遍历全表,效率较低
            expungeStaleEntry(i);
        else
            //递增下标i的值进行下一轮的查找
            i = nextIndex(i, len);
        e = tab[i];
    }
    return null;
}

2、remove()方法

1)获取当前用的线程,并找到线程关联的threadLocalMap

2)若不为空则删除threadLocalMap中关联的值,否则啥也不做

//ThreadLocal
public void remove() {
    ThreadLocalMap m = getMap(Thread.currentThread());
    if (m != null)
        //删除当前threadLocal对象关联的Entry
        m.remove(this);
}
 
//ThreadLocalMap
private void remove(ThreadLocal<?> key) {
    Entry[] tab = table;
    int len = tab.length;
    int i = key.threadLocalHashCode & (len-1);
    for (Entry e = tab[i];
         e != null;
         e = tab[i = nextIndex(i, len)]) {
        if (e.get() == key) {
            e.clear();
            expungeStaleEntry(i);
            return;
        }
    }
}

以上就是java中ThreadLocal核心方法介绍,大家会发现这些方法我们在其他的模块也有使用到。想要对其他核心方法有所了解,也可以在课后自行查阅资料。

免费视频教程
本教程部分素材来源于网络,版权问题联系站长!
相关文章
  Python中的ThreadLocal变量如何理解
  java中ThreadLocal是什么
  java threadLocal源码探究
相关视频章节
  什么是tkinter窗口
  例子3 登录窗口
  例子2 登录窗口
  例子1 登录窗口
  pack grid place 放置位置
作者信息

小妮浅浅

认证0级讲师

最近文章
python在协程中增加任务 436
python pyg2plot的原理 341
python中pyg2plot如何使用? 152
推荐视频
视频教程分类