ThreadLocal用法和实现原理
来源:互联网 发布:巨人网络收购alpha 编辑:程序博客网 时间:2024/05/21 10:35
转载自 http://www.cnblogs.com/alphablox/archive/2013/01/20/2869061.html
ThreadLocal用法和实现原理
ThreadLocal为解决多线程程序的并发不安全问题提供了一种新的解决思路。使用这个工具类可以很简洁地编写出优美的多线程程序。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
如果你定义了一个单实例的java bean,它有若干属性,但是有一个属性不是线程安全的,比如说HashMap。并且碰巧你并不需要在不同的线程中共享这个属性,也就是说这个属性不存在跨线程的意义。那么你不要sychronize这么复杂的东西,ThreadLocal将是你不错的选择。
举例来说:
import java.util.HashMap;
public class TreadLocalTest {
static ThreadLocal<HashMap> map0 = new ThreadLocal<HashMap>(){
@Override
protected HashMap initialValue() {
System.out.println(Thread.currentThread().getName()+"initialValue");
return new HashMap();
}
};
public void run(){
Thread[] runs = new Thread[3];
for(int i=0;i<runs.length;i++){
runs[i]=new Thread(new T1(i));
}
for(int i=0;i<runs.length;i++){
runs[i].start();
}
}
public static class T1 implements Runnable{
int id;
public T1(int id0){
id = id0;
}
public void run() {
System.out.println(Thread.currentThread().getName()+":start");
HashMap map = map0.get();
for(int i=0;i<10;i++){
map.put(i, i+id*100);
try{
Thread.sleep(100);
}catch(Exception ex){
}
}
System.out.println(Thread.currentThread().getName()+':'+map);
}
}
/**
* Main
* @param args
*/
public static void main(String[] args){
TreadLocalTest test = new TreadLocalTest();
test.run();
}
}
输出解释;
Thread-1:start
Thread-2:start
Thread-0:start
Thread-2initialValue
Thread-1initialValue
Thread-0initialValue
Thread-1:{0=100, 1=101, 2=102, 3=103, 4=104, 5=105, 6=106, 7=107, 8=108, 9=109}
Thread-2:{0=200, 1=201, 2=202, 3=203, 4=204, 5=205, 6=206, 7=207, 8=208, 9=209}
Thread-0:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}
可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。
进入Theadlocal代码,可以发现如下的片段;
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
这说明ThreadLocal确实只有一个变量,但是它内部包含一个map,针对每个thread保留一个entry,如果对应的thread不存在则会调用initialValue。
java里面的变量的作用范围,有的是局部变量,有的是成员变量。局部变量永远不存在线程安全问题,成员变量是所有的线程所共享的,ThreadLocal的出现就弥补了这两种范
围的一个不足,它比局部变量的范围要大,不仅仅是局限于一个方法块,但是又比成员变量的范围要小,因为它不会被多个线程共享,是线程独占的。
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和实现原理
- ThreadLocal用法和原理
- ThreadLocal用法与实现原理
- ThreadLocal用法详解和原理
- android ThreadLocal的原理解析和用法
- ThreadLocal的用法、原理和用途
- threadlocal用法及原理
- 2015多校联合训练总结(2)
- 设计模式_访问者模式
- UVa 215 - Spreadsheet Calculator(DFS)
- 线性回归模型
- keepalived+httpd+tomcat实现高可用负载均衡
- ThreadLocal用法和实现原理
- 基本排序算法之冒泡排序
- Javascript MVC 学习笔记(二) 控制器和状态
- 字符在转换为ISO-8859-1字符集时可能会遭到破坏
- pig 编程指南笔记
- 生活感悟_1
- 真的有必要写好技术博客
- Integer to Roman
- sphinx 的问题整理