浅析 ThreadLocal
一、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的更多相关文章
- 浅析ThreadLocal
这是我的第一篇博客,条理不是很清晰,不过还是希望能对大家有所帮助. 首先明确一下这个类的作用,ThreadLocal类是用来为每个线程提供了一份变量的副本,即每个线程的局部变量.每个线程都在自己的栈空 ...
- ThreadLocal 从源码角度简单分析
目录 ThreadLcoal源码浅析 ThreadLocal的垃圾回收 Java引用 ThreadLocal的回收 各线程中threadLocalMap的回收 内存泄露问题 总结 参考 ThreadL ...
- Java并发包2--ThreadLocal的使用及原理浅析
ThreadLocal 是本地线程变量,是一个以ThreadLocal对象为key,任意对象为value的存储结构. 一.使用案例 1.定义线程类MyThread,代码如下: public class ...
- ThreadLocal浅析
1.ThreadLocal的大体理解 ThreadLocal 又名 线程局部变量,是 Java 中一种较为特殊的 线程绑定机制,可以为每一个使用该变量的线程都提供一个变量值的副本,并且每一个线程都可以 ...
- 浅析Linux操作系统工作的基础
环境:lubuntu 13.04 kernel 3.9.7 作者:SA12226265 katao 简介: 本文根据 Linux™ 系统工作基础的分析,对存储程序计算机.堆栈(函数调用堆栈)机制和 ...
- spring源码浅析——IOC
=========================================== 原文链接: spring源码浅析--IOC 转载请注明出处! ======================= ...
- ThreadLocal原理分析与代码验证
ThreadLocal提供了线程安全的数据存储和访问方式,利用不带key的get和set方法,居然能做到线程之间隔离,非常神奇. 比如 ThreadLocal<String> thread ...
- 浅析MyBatis(三):聊一聊MyBatis的实用插件与自定义插件
在前面的文章中,笔者详细介绍了 MyBatis 框架的底层框架与运行流程,并且在理解运行流程的基础上手写了一个自己的 MyBatis 框架.看完前两篇文章后,相信读者对 MyBatis 的偏底层原理和 ...
- 老生常谈系列之Aop--Spring Aop原理浅析
老生常谈系列之Aop--Spring Aop原理浅析 概述 上一篇介绍了AspectJ的编译时织入(Complier Time Weaver),其实AspectJ也支持Load Time Weaver ...
随机推荐
- SVN使用方法总结
SVN使用方法 SVN版本管理模式:http://www.cnblogs.com/newstar/archive/2011/01/04/svn.html (集中式-trunk和分散式-branch ...
- (转) MFC的入口点与消息循环,消息映射
博文分析的很不错,尤其是替换默认窗口过程的这块,本人觉得,所有的这些都可以参阅侯杰的<深入浅出MFC >. 来自:http://blog.csdn.net/sryan/article/de ...
- P125、面试题19:二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像二叉树结点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTr ...
- Java API ——Object类
1.Object类概述 1)类层次结构的根类. 2)所有类都直接或者间接的继承自该类. 3)构造方法 · public Object() · 子 ...
- AOSP
定义编辑 "Android Open-Source Project"的缩写 中文意为"Android 开放源代码项目" 内容编辑 在Android Open-S ...
- Android开发之一个未解决的bug
使用Activity之间传递数据的时候,出现了一个bug,但是没有找到哪里出错了. 把代码和log都记录下来,以后研究 代码: MainActivity.class package com.examp ...
- [转] android自动化测试之MonkeyRunner使用实例(三)
一.使用CMD命令打开模拟器 运行monkeyrunner之前必须先运行相应的模拟器或连上设备,不然monkeyrunner无法连接设备. 1.1 用Elipse打开Android模拟器或在CMD中 ...
- 告诉你一个真实的OpenStack:都谁在用,用来干什么?
告诉你一个真实的OpenStack:都谁在用,用来干什么? OpenStack基金会近日发布的双年调查报告显示,开源云计算软件OpenStack正在进入主流企业市场,但该项目依然面临较难部署和管理的老 ...
- [原]Unity3D深入浅出 - 新版动画系统(Mecanim)
Mecanim概述: Mecanim是Unity提供第一个丰富而复杂的动画系统,提供了: 针对人形角色的简易的工作流和动画创建能力 Retargeting(运动重定向)功能,即把动画从一个角色模型应用 ...
- Java [leetcode 36]Valid Sudoku
题目描述: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board cou ...