文档章节

深入ThreadLocal的内部机制

yqbboy
 yqbboy
发布于 2012/10/27 23:00
字数 617
阅读 140
收藏 6

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本。 ThreadLocal的接口方法: void set(Object value):设置当前线程的线程局部变量的值。 public Object get():该方法返回当前线程所对应的线程局部变量。 public void remove():将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。 需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收, 所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。 protected Object initialValue():返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。 这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行, 并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。 在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。 ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本 模拟ThreadLocal代码清单: package cn.itcast.ref; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Random; public class MyThreadLocal { //使用同步的map维护对象 private static Map<Thread,Object> map = Collections.synchronizedMap(new HashMap<Thread,Object>()); public static Object get(){ //获取当前线程 Thread currentThread = Thread.currentThread(); Object o = map.get(currentThread); if(o==null){ o = new Random().nextInt(100);//假设是一个随机数 map.put(currentThread, o); } return o; } public static void remove(){ Thread currentThread = Thread.currentThread(); if(map.containsKey(currentThread)){ map.remove(currentThread); } } } 虽然这个ThreadLocal实现版本显得比较幼稚,但它和JDK所提供的ThreadLocal类在实现思路上是相近的。

测试代码清单: @Test public void testMyThreadLocal(){ Object o1 = MyThreadLocal.get(); Object o2 = MyThreadLocal.get(); //以下因为是同一个线程所有值相同 System.err.println(o1+","+o2); new Thread(){ public void run() { //在新的线程中获取对象为不同的值 Object o3 = MyThreadLocal.get(); System.err.println("o3:"+o3); }; }.start(); }

© 著作权归作者所有

yqbboy
粉丝 2
博文 2
码字总数 894
作品 0
海淀
程序员
私信 提问
Java程序员从笨鸟到菜鸟之(九十八)深入java虚拟机(七)深入源码看java类加载器ClassLoader

欢迎阅读本专题的其他博客: 深入java虚拟机(一)——java虚拟机底层结构详解 深入java虚拟机(二)——类的生命周期(上)类的加载和连接 深入java虚拟机(三)——类的生命周期(下)类的初...

长平狐
2012/11/12
179
0
结合JVM源码谈Java类加载器

一、前言 之前文章 Java 类加载器揭秘 从Java层面讲解了Java类加载器的原理,这里我们结合JVM源码在稍微深入讲解下。 二、Java类加载器的委托机制 Java 类加载器使用的是委托机制,也就是一个...

阿里加多
2018/04/29
0
0
你所需要的java提升篇大总结

java基础篇深入解析大总结 java基础(一) 深入解析基本类型 java基础(二) 自增自减与贪心规则 java基础(三) 加强型for循环与Iterator java基础(四) java运算顺序的深入解析 java基础(五) Str...

sihailoveyan
2018/04/25
0
0
JVM 虚拟机(对象创建,类加载器,执行引擎等),

1.揭开 Java 对象创建的奥秘? 2.class 文件结构详解? 3.详解 Java 类的加载过程? > Java 对象创建,class 文件结构 Java对象模型 。Java对象保存在堆内存中。在内存中,一个Java对象包含三...

desaco
2018/08/29
0
0
Java程序员从笨鸟到菜鸟全部博客目录【2012年十一月七日更新】

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,...

长平狐
2012/11/12
201
0

没有更多内容

加载失败,请刷新页面

加载更多

Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
32分钟前
5
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
今天
8
0
详解箭头函数和普通函数的区别以及箭头函数的注意事项、不适用场景

箭头函数是ES6的API,相信很多人都知道,因为其语法上相对于普通函数更简洁,深受大家的喜爱。就是这种我们日常开发中一直在使用的API,大部分同学却对它的了解程度还是不够深... 普通函数和...

OBKoro1
今天
5
0
轻量级 HTTP(s) 代理 TinyProxy

CentOS 下安装 TinyProxy yum install -y tinyproxy 启动、停止、重启 # 启动service tinyproxy start# 停止service tinyproxy stop# 重启service tinyproxy restart 相关配置 默认...

Anoyi
今天
2
0
Linux创建yum仓库

第一步、搞定自己的光盘 #创建文件夹 mkdir -p /media/cdrom #挂载光盘 mount /dev/cdrom /media/cdrom #编辑配置文件使其永久生效 vim /etc/fstab 第二步,编辑yun源 vim /ect yum.repos.d...

究极小怪兽zzz
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部