一、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. SVN使用方法总结

    SVN使用方法   SVN版本管理模式:http://www.cnblogs.com/newstar/archive/2011/01/04/svn.html (集中式-trunk和分散式-branch ...

  2. (转) MFC的入口点与消息循环,消息映射

    博文分析的很不错,尤其是替换默认窗口过程的这块,本人觉得,所有的这些都可以参阅侯杰的<深入浅出MFC >. 来自:http://blog.csdn.net/sryan/article/de ...

  3. P125、面试题19:二叉树的镜像

    题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像二叉树结点的定义如下:struct BinaryTreeNode{       int     m_nValue;       BinaryTr ...

  4. Java API ——Object类

    1.Object类概述 1)类层次结构的根类.       2)所有类都直接或者间接的继承自该类. 3)构造方法            · public Object()            · 子 ...

  5. AOSP

    定义编辑 "Android Open-Source Project"的缩写 中文意为"Android 开放源代码项目" 内容编辑 在Android Open-S ...

  6. Android开发之一个未解决的bug

    使用Activity之间传递数据的时候,出现了一个bug,但是没有找到哪里出错了. 把代码和log都记录下来,以后研究 代码: MainActivity.class package com.examp ...

  7. [转] android自动化测试之MonkeyRunner使用实例(三)

    一.使用CMD命令打开模拟器 运行monkeyrunner之前必须先运行相应的模拟器或连上设备,不然monkeyrunner无法连接设备. 1.1  用Elipse打开Android模拟器或在CMD中 ...

  8. 告诉你一个真实的OpenStack:都谁在用,用来干什么?

    告诉你一个真实的OpenStack:都谁在用,用来干什么? OpenStack基金会近日发布的双年调查报告显示,开源云计算软件OpenStack正在进入主流企业市场,但该项目依然面临较难部署和管理的老 ...

  9. [原]Unity3D深入浅出 - 新版动画系统(Mecanim)

    Mecanim概述: Mecanim是Unity提供第一个丰富而复杂的动画系统,提供了: 针对人形角色的简易的工作流和动画创建能力 Retargeting(运动重定向)功能,即把动画从一个角色模型应用 ...

  10. Java [leetcode 36]Valid Sudoku

    题目描述: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board cou ...