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,虽然他们同时执行。
可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。
可以看到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。
threadlocal彻底理解的更多相关文章
- ThreadLocal深入理解二
		
转载:http://doc00.com/doc/101101jf6 今天在看之前转载的博客:ThreadLocal的内部实现原理.突然有个疑问, 按照threadLocal的原理, 当把一个对象存入到 ...
 - ThreadLocal深入理解一
		
转载:http://www.cnblogs.com/dolphin0520/p/3920407.html 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使 ...
 - Java中的ThreadLocal深入理解
		
提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...
 - ThreadLocal的理解与应用场景分析
		
对于Java ThreadLocal的理解与应用场景分析 一.对ThreadLocal理解 ThreadLocal提供一个方便的方式,可以根据不同的线程存放一些不同的特征属性,可以方便的在线程中进行存 ...
 - Python中ThreadLocal的理解与使用
		
一.对 ThreadLocal 的理解 ThreadLocal,有的人叫它线程本地变量,也有的人叫它线程本地存储,其实意思一样. ThreadLocal 在每一个变量中都会创建一个副本,每个线程都可以 ...
 - java中threadlocal的理解
		
[TOC] #java中threadlocal的理解##一.threadlocal的生命周期和ThreadLocalMap的生命周期可以吧TreadLocal看做是一个map来使用,只不过这个map是 ...
 - ThreadLocal简单理解
		
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
 - threadlocal彻底理解,深刻
		
本文转自http://blog.csdn.net/huachao1001/article/details/51970237 ThreadLocal的使用相信大家都比较熟悉,但是ThreadLocal内 ...
 - 我对ThreadLocal的理解
		
声明:小弟菜狗一个.对ThreadLocal的描写叙述和理解难免有所偏差 近期由于须要深入的了解android的handler消息机制而去查看了Looper的源代码.众所周知在主线程中是不须要在程序猿 ...
 - ThreadLocal深入理解与内存泄露分析
		
ThreadLocal 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本.所以每个线程都能够独立地改变自己的副本.而不会影响其他线程所相应的副本. ...
 
随机推荐
- ubuntu16.04 使用问题笔记
			
1.问题: 下列软件包有未满足的依赖关系: vim : 依赖: vim-common (= 2:7.4.826-1ubuntu1) 但是 2:7.4.1689-3ubuntu1 正要被安装 E: 无法 ...
 - spring security注解(1)
			
Chapter 15. 基于表达式的权限控制 Spring Security 3.0介绍了使用Spring EL表达式的能力,作为一种验证机制 添加简单的配置属性的使用和访问决策投票,就像以前一样. ...
 - BeanUtils Date
			
在jdbc封装(基础的CRUD)的时候(查询一条数据,查询多条数据,更新....)经常会用到一个BeanUtil来设置属性值,当对象中存在Date类型的时候,会报错:如下: 2017-11-03 13 ...
 - [poj] 3304 Segments || 判断线段相交
			
原题 给出n条线段,判断是否有一条直线与所有线段都有交点 若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件. 每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点 ...
 - 做一个类似JQuery获取DOM对象的$()
			
在dom操作时,有时根据id获取单个对象.有时根据className获取多个对象.平常可能我们用两个函数来实现这两个功能.不过我将它们整合了一下,目前使用情况良好,函数如下: view source ...
 - Educational Codeforces Round 42 (Rated for Div. 2) C
			
C. Make a Square time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
 - Java中的抽象和封装
			
一.面向对象和面向过程的区别 面向对象: 核心:封装了属性和方法的类,以数据为中心,实现了类级别的代码重用 面向对象因为采用了类,所以具有继承和多态特性,可以进一步重用代码和简化编程 面向过程: 核心 ...
 - [ CodeVS冲杯之路 ] P1098
			
不充钱,你怎么AC? 题目:http://codevs.cn/problem/1098/ 显然就是使每堆牌达到总体的平均数,尽量使每次移动时的牌数最大,这就类似于飞行棋,将几个棋子叠起来一起走是最优 ...
 - 使用 padding-bottom 设置高度基于宽度的自适应
			
我们在做移动端列表,通常会做到图文列表,列表是自适应的.当列表中有图片,图片的宽度是随着列表宽的变化而变化,我们为了在图片宽度变化的时候做到图片的不变形,所有采用以下办法. 本文章只讲语法 html ...
 - (十一)Ubuntu下面怎么找到一个软件安装的目录,卸载软件
			
aptitude show packagename 实例: aptitude show sublime-text-installer 可以看到这个软件一系列信息 dpkg命令 dpkg -l //列车 ...