一、ThreadLocal类说明

  ThreadLocal,很容易让人望文生义,直译"本地线程"。ThreadLocal不是一个thread,是thread的局部变量。使用ThreadLocal维护变量时,它为每个使用它的线程提供独立的线程副本,每个线程可以改变自己的副本,而不会影响到其它线程对应的副本。

  从线程的角度看,目标变量就象是线程的本地变量,这也是类名中"Local"所要表达的意思。

二、ThreadLocal常用方法

①、当前变量的初始值
  protected T initialValue()

源码 如下,该方法是一个protected方法,显然是为了让子类覆盖而设计的。该方法是在get|set会调用,且只会被调一次。ThreadLocal缺省实现直接返回null

protected T initialValue() {
return null;
}

②、设置当前线程的线程局部变量值

  void set(T value)

③、返回当前线程的线程局部变量值

  public T get()

④、删除当前线程的线程局部变量值,节省内存的占用。

  public void remove()

三、下面我们通过一个具体例子,看看ThreadLocal的具体用法---Id生成器

id生成器

public interface Sequence {

    public int getId();
} public class LocalSequenceImpl implements Sequence { private ThreadLocal<Integer> container = new ThreadLocal<Integer>() { @Override
protected Integer initialValue() {
return 0;
};
}; @Override
public int getId() {
container.set(container.get() + 1);
return container.get();
} }

线程

public class ThreadLocalDemo extends Thread {

    private static Sequence obj;

    @SuppressWarnings("static-access")
public ThreadLocalDemo(Sequence obj) {
this.obj = obj;
} public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " : " + obj.getId());
}
} public static void main(String[] args) { Sequence obj = new LocalSequenceImpl(); test(obj); } static void test(Sequence obj) { ThreadLocalDemo thread1 = new ThreadLocalDemo(obj); ThreadLocalDemo thread2 = new ThreadLocalDemo(obj); ThreadLocalDemo thread3 = new ThreadLocalDemo(obj); thread1.start();
thread2.start();
thread3.start();
}
}

结果  :

Thread-0 : 1
Thread-1 : 1
Thread-1 : 2
Thread-2 : 1
Thread-2 : 2
Thread-2 : 3
Thread-1 : 3
Thread-0 : 2
Thread-0 : 3

从上述结果,每个线程只会更改自己的局部变量,并没有发生互相干扰的情况。可以看出来,ThreadLocal为使用它的线程提供独立的副本。

不信?我们下面再通过一个不使用ThreadLocal来验证下。

public class SequenceImpl implements Sequence {

    private static int id = 0;

    @Override
public int getId() {
id = id + 1;
return id;
}
}

结果

Thread-0 : 2
Thread-0 : 4
Thread-0 : 5
Thread-2 : 3
Thread-2 : 6
Thread-2 : 7
Thread-1 : 1
Thread-1 : 8
Thread-1 : 9

仔细观察下结果,三个线程同时访问一个局部变量id,发生了互相干扰的情况。

四、拓展

看下ThreadLocal源码,底层是用Map实现的。我们可以自己设计一个ThreadLocal

public class MyThreadLocal<T> {

    private Map<Thread, T> container = Collections.synchronizedMap(new HashMap<>());

    public void set(T value) {
container.put(Thread.currentThread(), value);
} public T get() {
Thread currentThread = Thread.currentThread();
T value = container.get(Thread.currentThread());
if(value == null && !container.containsKey(currentThread)) {
value = initialValue();
container.put(Thread.currentThread(), value);
}
return value;
} protected T initialValue() {
return null;
}
}

浅析 ThreadLocal的更多相关文章

  1. 浅析ThreadLocal

    这是我的第一篇博客,条理不是很清晰,不过还是希望能对大家有所帮助. 首先明确一下这个类的作用,ThreadLocal类是用来为每个线程提供了一份变量的副本,即每个线程的局部变量.每个线程都在自己的栈空 ...

  2. ThreadLocal 从源码角度简单分析

    目录 ThreadLcoal源码浅析 ThreadLocal的垃圾回收 Java引用 ThreadLocal的回收 各线程中threadLocalMap的回收 内存泄露问题 总结 参考 ThreadL ...

  3. Java并发包2--ThreadLocal的使用及原理浅析

    ThreadLocal 是本地线程变量,是一个以ThreadLocal对象为key,任意对象为value的存储结构. 一.使用案例 1.定义线程类MyThread,代码如下: public class ...

  4. ThreadLocal浅析

    1.ThreadLocal的大体理解 ThreadLocal 又名 线程局部变量,是 Java 中一种较为特殊的 线程绑定机制,可以为每一个使用该变量的线程都提供一个变量值的副本,并且每一个线程都可以 ...

  5. 浅析Linux操作系统工作的基础

    环境:lubuntu 13.04   kernel 3.9.7 作者:SA12226265 katao 简介: 本文根据 Linux™ 系统工作基础的分析,对存储程序计算机.堆栈(函数调用堆栈)机制和 ...

  6. spring源码浅析——IOC

    =========================================== 原文链接: spring源码浅析--IOC   转载请注明出处! ======================= ...

  7. ThreadLocal原理分析与代码验证

    ThreadLocal提供了线程安全的数据存储和访问方式,利用不带key的get和set方法,居然能做到线程之间隔离,非常神奇. 比如 ThreadLocal<String> thread ...

  8. 浅析MyBatis(三):聊一聊MyBatis的实用插件与自定义插件

    在前面的文章中,笔者详细介绍了 MyBatis 框架的底层框架与运行流程,并且在理解运行流程的基础上手写了一个自己的 MyBatis 框架.看完前两篇文章后,相信读者对 MyBatis 的偏底层原理和 ...

  9. 老生常谈系列之Aop--Spring Aop原理浅析

    老生常谈系列之Aop--Spring Aop原理浅析 概述 上一篇介绍了AspectJ的编译时织入(Complier Time Weaver),其实AspectJ也支持Load Time Weaver ...

随机推荐

  1. fedora SSH

    设置无密码登陆时注意:chmod 0700 .ssh chmod 600 ~/.ssh/authorized_keys  cat /root/.ssh/id_rsa.pub  >> /ro ...

  2. 游戏中VIP会员模块的简单实现

    哈哈  今天周末有时间,再整理一篇博文上来,虽然已经不做游戏老长时间了,但还是要把以前做过的东西总结一下,借此可以回顾以前的东西,也可以分享给大家. 今天说一下游戏中VIP会员模块的实现思路.每款游戏 ...

  3. windows下的go语言的环境搭建和初探

    闲话不说,直入主题. 1.准备工具 a.windows下的Go语言开发安装包 官方下载地址:https://code.google.com/p/go/downloads/list b.Go语言中文官网 ...

  4. 【HDOJ】5296 Annoying problem

    LCA+RMQ.挺不错的一道题目. 思路是如何通过LCA维护费用.当加入新的点u是,费用增量为dis[u]-dis[lca(u, lower_u)] - dis[lca(u, greater_u)] ...

  5. html5自带表单验证-美化改造

    神奇的代码 暂且叫做html5.css /* === HTML5 validation styles === */ .myform select:required, .myform input:req ...

  6. JAVA并行框架学习之ForkJoin

    当硬件处理能力不能按照摩尔定律垂直发展的时候,选择了水平发展,多核处理器已经广泛应用.未来随着技术的进一步发展,可能出现成百上千个处理核心,但现有的程序运行在多核心处理器上并不能得到较大性能的提升,主 ...

  7. FormsAuthentication实现单点登录

    原文地址:http://www.wlm.so/Article/Detail/lmb48bk9f690n00000 单点登录,这种在网络非常常见,在这里讨论的是实现同一主域下的子站间的单点登录,同样也适 ...

  8. bzoj1079: [SCOI2008]着色方案

    ci<=5直接想到的就是5维dp了...dp方程YY起来很好玩...写成记忆化搜索比较容易 #include<cstdio> #include<cstring> #inc ...

  9. 使用Zxing实现扫二维码描

    1.集成Zxing.bar 2.复制代码到项目中 3.修改 MipacActivityCapture.java  的扫描结果方法 handleDecode() /** * 处理扫描结果,实现活动页面跳 ...

  10. 【原】cocos2d-x开发笔记:多点触控

    在项目开发中,我们做的大地图,一个手指头按下滑动可以拖动大地图,两个手指头按下张开或者闭合,可以放大和缩小地图 在实现这个功能的时候,需要使用到cocos2d-x的多点触控功能. 多点触控事件,并不是 ...