首页 > 编程知识 正文

threadlocal原理和用法,threadlocal实现原理

时间:2023-05-06 08:26:31 阅读:281370 作者:1884

ThreadLocal称为线程本地变量,其为变量在每个线程中都创建了一个副本,每个线程都访问和修改本线程中变量的副本。

       应用示例:

ThreadLocal<SimpleDateFormat> t1=new ThreadLocal<>();

       可以看出,为每个线程分配一个变量副本的工作并不是由ThreadLocal实现的,需要在应用层面实现,ThreadLocal只是提供一个容器。如果在应用上为每个线程分配了同一个对象实例,那ThreadLocal也无法保证线程安全。

4.3.1 ThreadLocal实现原理

       ThreadLocal的内部实现,主要关注的就是set()和put()方法。

       set()方法:

Thread类内部有一个实例变量:

ThreadLocal.ThreadLocalMap threadLocals = null;

       在执行set()方法时首先获得当前线程对象,通过getMap()得到当前线程的ThreadLocalMap(类似于HashMap的一种Map,但是没有实现Map接口,所以严格地说,它只是一种类)。并将相应的数据存入到ThreadLocalMap中。该map中保存了当前线程的所有的“本地变量”,也就是说当前线程可能有多个ThreadLocal类的实例,每个实例保存的变量副本都在这个map中。写入map中的键值对,键是调用set()方法的那个ThreadLocal实例,值就是副本变量。如果当前线程对应的map为空,则为该线程创建一个ThreadLocalMap,并将键值对存入进去。

       get()方法:

       get()方法是先取得当前线程对应的ThreadLocalMap对象,然后将调用get()方法的ThreadLocal对象作为key取得对应的变量。如果该线程对应的map不存在,则为其创建ThreadLocalMap对象,并将键值对的key设为当前ThreadLocal,value置为空。如果map存在,对应的Entry不存在,则初始化键值对如之前。

       如果线程关闭,Thread类会进行一些清理工作,包括清理ThreadLocalMap。但是如果使用线程池,由于线程可能并不是真正的关闭(比如newFixedThreadPool会保持线程一只存活)。因此,如果将一些大对象存放到ThreadLocalMap中,可能会造成内存泄漏。因为线程没有关闭,无法回收,但是这些对象不会再被使用了。如果希望及时回收对象,则可以使用Thread.remove()方法将变量移除。

       ThreadLocal使用场景:最常见的ThreadLocal使用场景为用来解决数据库连接、Session管理等。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。