ThreadLocal 为线程绑定对象

本文深入解析Java中的ThreadLocal类,介绍其使用场景、核心方法、内部实现原理,并给出具体示例。此外,还探讨了知名框架如Spring MVC中ThreadLocal的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java.lang.ThreadLocal<T>

类,对它的调用在不同线程中有不同的结果。

1.使用场景

有些类不是线程安全的,若想在多线程下使用,我们可以为每个线程绑定一个此类的对象。

2.常用方法

T java.lang.ThreadLocal. get()
返回当前线程所持有的对象。
void java.lang.ThreadLocal. set(T value)
设置当前线程所持有的对象。
void java.lang.ThreadLocal. remove()
移除当前线程所持有的对象。

3.例子

可见:线程安全

4.原理浅析

第一段,个人发挥。
//如果让我写,我会直接明了的实现
class ThreadLocalByYichu
   
    {
	hashmap
    
      map=new HashMap<>();
	
	T get(){
		return map.get(Thread.currentThread());
	}
	
}
//而JDK中把map放到了Thread中,并且key是ThreadLocal的实例,很个性。
class java.lang.Thread{
	//思想是这样的,但由特殊的ThreadLocal.ThreadLocalMap实现。
	Map
     
       map;
}

     
    
   
第二段,摘自jdk。
/*
不同jdk版本,同一个类的实现可能作修改,以下信息对应于jre_1.8.0_111版本。
*/
class java.lang.Thread{
	/* 依附于当前线程的ThreadLocal 的一些值,此字段只由 ThreadLocal这个类来维护. */
	//注意这个ThreadLocal.ThreadLocalMap跟java.util.Map
  
   一点关系都没有。
	ThreadLocal.ThreadLocalMap threadLocals = null;
	/*other fields and functions*/
}

class java.lang.ThreadLocal
   
    {
	//内部静态类
	static class ThreadLocalMap{
		//内部静态类的内部静态类
		//当一个实例只被弱引用持有时,允许GC时被回收。这么设计防止ThreadLocalMap不必要的膨胀。
		static class Entry extends WeakReference
    
     > {
            /** The value associated with this ThreadLocal. */
            Object value;
            Entry(ThreadLocal
      k, Object v) {
                super(k);
                value = v;
            }
        }
		/*other fields and functions*/
	}
	ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
	public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
    private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }
	
	protected T initialValue() {
        return null;
    }

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
	void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }
	/*other fields and functions*/
}

    
   
  


5.知名框架如何用

springmvc就在用。
package org.springframework.web.context.request;
/**
 * Holder class to expose the web request in the form of a thread-bound
 * {@link RequestAttributes} object 
 * ...
 */
public abstract class RequestContextHolder  {
	private static final ThreadLocal<RequestAttributes> requestAttributesHolder;
	/*other fields and functions*/
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值