多语言展示
当前在线:1765今日阅读:26今日分享:39

如何认识和理解ThreadLocal

jdk自带的ThreadLocal类,一般都知道有这么一个类,但很多人也许不知道这个类是干嘛用的,在什么地方需要用到这个类。光从类名上看,也很难知道这个类的用途,容易误解为本地线程,其实它根本就不是线程。ThreadLocal是解决多线程的并发访问的一种方式,为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。下面结合示例代码来介绍下ThreadLocal类
工具/原料
1

jdk1.2及以上

2

idea开发工具

方法/步骤
1

认识ThreadLocal类,首先看下这个类的常用方法getMap和createMap方法,createMap里创建了一个ThreadLocalMap实例,并被线程Thread t所强引用,也就是说ThreadLocalMap的生命周期跟Thread一样长,如果线程没有销毁,ThreadLocalMap实例也不会被回收

2

void set(T value)方法,map.set(this, value),是以ThreadLocal对象为key存储了value值,第一次set,则会调用createMap方法创建ThreadLocalMap。set内部调用的set方法有优化清除的操作

3

T get()方法,map.getEntry(this)可以看出,是通过ThreadLocal作为key来找到之前set进去的value对象

4

void remove()方法,是jdk1.5开始添加的,将当前线程局部变量的值删除,是为了快速释放内存,不是必须调用的,因为线程结束后会自动回收线程局部变量

5

看ThreadLocal的源码可以看到,创建ThreadLocalMap的时候new Entry对象出来,这个Entry实际是继承了WeakReference类,这就表示在持有ThreadLocal对象实例的时候,是弱引用关系,这个是为了使ThreadLocal的回收不受ThreadLocalMap影响,从而在ThreadLocal被回收之后,对应的value在下一次ThreadLocalMap调用set,get,remove的时候会被清除

6

最后给出一个使用ThreadLocal的例子代码/** * 测试线程局部变量 * Created by shaowei on 2017/8/15. */public class TestThreadLocal {    private static ThreadLocal threadLocal            = new ThreadLocal() {        public Integer initialValue(){            return 0;        }    };    public int getNextNum(){        threadLocal.set(threadLocal.get()+1);        return threadLocal.get();    }    public static void main(String[] args){        TestThreadLocal sn = new TestThreadLocal();        new TestThread(sn).start();        new TestThread(sn).start();        new TestThread(sn).start();    }    private static class TestThread extends Thread {        private TestThreadLocal tl;        public TestThread(TestThreadLocal tl){            this.tl = tl;        }        public void run(){            for(int i=0;i<5;i++){                System.out.println('Thread['+Thread.currentThread().getName()                        +']tl['+tl.getNextNum()+']');            }        }    }}

7

运行示例代码之后,打印结果可以看出,多个线程递增的序列数字没有混乱,说明存储在线程局部变量中,确实是解决了多线程并发冲突。

注意事项

使用完ThreadLocal建议手动调用下remove方法,虽然不是必须的,但可以加快内存释放,还可以避免因为线程长时间无法结束而到导致ThreadLocal的内存泄漏

推荐信息