深入理解Java中的ThreadLocal

java 文章 2022-07-15 14:09 0 全屏看文

转自:

http://www.java265.com/JavaCourse/202205/3370.html

下文笔者讲述java中ThreadLocal的详解说明,如下所示:

ThreadLocal简介

ThreadLocal的功能:   用于创建线程局部变量的类----------------------------------------------------------------------------我们都知道我们创建的变量,可以被任何一个线程访问和修改但是当我们使用ThreadLocal创建的变量只能被当前线程访问,其他线程无法访问和修改-----------------------------------------------------------------------------

ThreaLocal用法示例

ThreadLocal定义:   ThreadLocal<String> threadLocalInfo = new ThreadLocal<>();set方法    threadLocalInfo.set("java265.com");get方法   threadLocalInfo.get();完整的示例 private void testThreadLocal() {    Thread t = new Thread() {        ThreadLocal<String> threadLocalInfo = new ThreadLocal<>();        @Override        public void run() {            super.run();            threadLocalInfo.set("java265.com--我最爱的网站");            threadLocalInfo.get();        }    };    t.start();}

ThreadLocal初始值--设置方法

ThreadLocal设置默认的get初始值
  需要重写initialValue方法

例:ThreadLocal<String> mThreadLocal = new ThreadLocal<String>() {    @Override    protected String initialValue() {      return Thread.currentThread().getName();    }};

ThreadLocal的set方法原理说明

 set方法源码:public void set(T value) {    Thread t = Thread.currentThread();    ThreadLocalMap map = getMap(t);    if (map != null)        map.set(this, value);    else        createMap(t, value);} getMap: ThreadLocalMap getMap(Thread t) {    return t.threadLocals;}class Thread implements Runnable {    ThreadLocal.ThreadLocalMap threadLocals = null;}当一开始设置,即ThreadLocalMap对象未创建则新建ThreadLocalMap对象,并设置初始值void createMap(Thread t, T firstValue) {    t.threadLocals = new ThreadLocalMap(this, firstValue);}

ThreadLocal导致内存泄露的原因说明

  ThreadLocal实例被线程的ThreadLocalMap实例持有,也可以看成被线程持有。  当我们使用了线程池,由于之前的线程实例处理完之后出于复用的目的依然存活  即ThreadLocal设定的值被持有,才会导致内存泄露   ThreadLocal并不会产生内存泄露  因为ThreadLocalMap在选择key的时候  并不是直接选择ThreadLocal实例   而是ThreadLocal实例的弱引用。

static class ThreadLocalMap {/*** The entries in this hash map extend WeakReference, using* its main ref field as the key (which is always a* ThreadLocal object).  Note that null keys (i.e. entry.get()* == null) mean that the key is no longer referenced, so the* entry can be expunged from table.  Such entries are referred to* as "stale entries" in the code that follows.*/    static class Entry extends WeakReference<ThreadLocal<?>> {        /** The value associated with this ThreadLocal. */        Object value;        Entry(ThreadLocal<?> k, Object v) {            super(k);            value = v;        }    }}

ThreadLocal使用场景

 如:tractional     一个数据库连接,在一个线程中只此一份,所以可使用ThreadLocal实现线程间变量共享
-EOF-