首先来看ThreadLocal模式的实现机理:
在JDK的早期版本中,提供了一种解决多线程并发问题的方案:java.lang.ThreadLocal类。ThreadLocal类在维护变量时,世纪使用了当前线程(Thread)的一个叫做ThreadLocalMap的独立副本,每个线程可以独立修改属于自己的副本而不会互相影响,从而隔离了线程和线程,避免了线程访问实例变量发生冲突的问题。
ThreadLocal本身并不是一个线程而是通过操作当前线程中的一个内部变量来达到与其他线程隔离的目的。
ThreadLocal模式至少从两个方面完成了数据访问隔离,即横向隔离和纵向隔离,有了横向隔离和纵向两种不同的隔离方式,ThreadLocal模式就能真正的做到线程安全:
纵向隔离:线程与线程之间的数据访问隔离。这一点由线程的数据结构保证。因为每个线程都在进行对象访问时,访问的都是各个线程自己的ThreadLocalMap
横向隔离:同一个线程中,不同的ThreadLocal实例操作的对象之间相互隔离,这一点由ThreadLocalMap在存储时采用当前ThradLocal的实例作为key来保证。

深入比较ThreadLocal模式与synchronized关键字:
ThreadLocal模式与synchronized关键字都用于处理多线程并发访问变量的问题,只是二者处理问题的角度和思路不同。
1)ThreadLocal是一个Java类,通过对当前线程中的局部变量的操作来解决不同线程的变量访问的冲突问题。所以,ThreadLocal提供了线程安全的共享对象机制,每个线程都拥有其副本。
2)Java中的synchronized是一个保留字,它依靠JVM的锁机制来实现临界区的函数或者变量在访问中的原子性。在同步机制中。通过对象的锁机制保证同一时间只有一个线程访问变量。此时,被用作“锁机制”的变量是多个线程共享的。
同步机制(synchronized关键字)采用了“以时间换空间”的方式,提供一份变量,让不同的线程排队访问。而ThreadLocal采用了“以空间换时间”的方式,为每一个线程都提供一份变量的副本,从而实现同时访问而互不影响。
使用ThreadLocal模式的步骤:
1)建立一个雷,并在其中封装一个静态的ThreadLocal变量,使其成为一个共享数据环境。
2)在类中实现访问静态ThreadLocal变量的静态方法(设值和取值)

要完成ThreadLocal模式其中最关键的就是创建一个任何地方都可以访问到的ThreadLocal实例,我们通过类的静态实例变量来实现这个用于承载静态实例变量的类就被视作一个共享环境

例子:

package com.slp.ThreadLocal;

public class Counter {

	/**
* 新建一个静态的ThreadLocal变量,并通过get方法将其变为一个可访问的对象
*/
private static ThreadLocal<Integer> counterContext = new ThreadLocal<Integer>() {
protected synchronized Integer initialValue() {
return 10;
}
}; /**
* 通过静态的get方法访问ThreadLocal中存储的值
*
* @return
*/
public static Integer get() {
return counterContext.get();
} /**
* 通过静态的set方法将变量值设置到ThreadLocal中
*
* @param value
*/
public static void set(Integer value) {
counterContext.set(value);
} /**
* 封装业务逻辑,操作存储于ThreadLocal中的变量
*/
public static Integer getNextCounter() {
counterContext.set(counterContext.get() + 1);
return counterContext.get();
} }

  这个类中,我们实现了一个静态的ThreadLocal变量,并通过get方法将ThreadLocal中存储的值暴漏处理,还封装了一个带有业务逻辑的方法getNextCounter,操作ThreadLocal中的值将其加1,并返回计算后的值。

这时这个Counter类就变成了一个数据共享环境,我们也拥有了实现ThreadLocal模式的关键要素。

package com.slp.ThreadLocal;

public class ThreadLocalTest extends Thread {
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("Thread[" + Thread.currentThread().getName()
+ "],counter=" + Counter.getNextCounter());
}
} }

  这是一个简单的线程类,循环输出当前线程的名称和getNextCounter的结果,由于getNextCounter中的逻辑所曹组的是ThreadLocal中的变量,也就是说,在同一个线程中,变量值会被连续累加。

package com.slp.ThreadLocal;

public class Test {

	public static void main(String[] args) {
// TODO Auto-generated method stub ThreadLocalTest testThrad1 = new ThreadLocalTest();
ThreadLocalTest testThrad2 = new ThreadLocalTest();
ThreadLocalTest testThrad3 = new ThreadLocalTest();
testThrad1.start();
testThrad2.start();
testThrad3.start(); } }

  执行结果:

Thread[Thread-2],counter=11
Thread[Thread-2],counter=12
Thread[Thread-2],counter=13
Thread[Thread-1],counter=11
Thread[Thread-0],counter=11
Thread[Thread-0],counter=12
Thread[Thread-0],counter=13
Thread[Thread-1],counter=12
Thread[Thread-1],counter=13

  由此可以看出这个访问是线程安全的。

ThreadLocal模式最合适的使用场景:在同一个线程的不同开发层次中共享数据、

实现ThreadLocal模式的两个主要步骤:

1.建立一个类,并在其中封装一个静态的ThreadLocal变量使其成为一个共享的数据环境

2.在类中实现访问静态ThreadLocal变量的静态方法(设置和取值)

ThreadLocal模式的核心元素的更多相关文章

  1. Struts2中的设计模式----ThreadLocal模式

    http://www.cnblogs.com/gw811/archive/2012/09/07/2675105.html 设计模式(Design pattern):是经过程序员反复实践后形成的一套代码 ...

  2. 【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式

    [转]Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式 博客分类: 企业应用面临的问题 java并发编程 Struts2的线程安全ThreadLocal模式St ...

  3. 【Java EE 学习 19】【使用过滤器实现全站压缩】【使用ThreadLocal模式解决跨DAO事务回滚问题】

    一.使用过滤器实现全站压缩 1.目标:对网站的所有JSP页面进行页面压缩,减少用户流量的使用.但是对图片和视频不进行压缩,因为图片和视频的压缩率很小,而且处理所需要的服务器资源很大. 2.实现原理: ...

  4. HTML核心元素

    一 HTML核心元素 1.文本标题 <h1>一级标题</h1> <h2>二级标题</h2> <h3>三级标题</h3> ... ...

  5. 【深入比较ThreadLocal模式与synchronized关键字】

    [深入比较ThreadLocal模式与synchronized关键字]ThreadLocal模式与synchronized关键字都是用于处理多线程并发访问变量的问题.只是两者处理问题的角度和思路不同. ...

  6. ThreadLocal模式探索

    一.首先,ThreadLocal模式使共享数据能多个线程被访问,每个线程访问的只是这个数据的副本,线程之间互不影响. 例子1: package Thread2; public class Counte ...

  7. ThreadLocal模式的原理

    在JDK的早期版本中,提供了一种解决多线程并发问题的方案:java.lang.ThreadLocal类.ThreadLocal类在维护变量时,实际使用了当前线程(Thread)中的一个叫做Thread ...

  8. 【UML】NO.54.EBook.6.UML.2.002-【Thinking In UML 大象 第二版】- UML 核心元素

    1.0.0 Summary Tittle:[UML]NO.54.EBook.6.UML.2.002-[Thinking In UML 大象 第二版]- UML 核心元素 Style:DesignPat ...

  9. ThreadLocal模式与synchronized关键字的比较

    ThreadLocal模式与synchronized关键字都是用于处理多线程并发访问变量的问题.只是两者处理问题的角度和思路不同. 1)ThreadLocal是一个Java类,通过对当前线程(Thre ...

随机推荐

  1. 17082 两个有序数序列中找第k小

    17082 两个有序数序列中找第k小 时间限制:1000MS  内存限制:65535K 提交次数:0 通过次数:0 题型: 编程题   语言: 无限制 Description 已知两个已经排好序(非减 ...

  2. Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for …

    编译通过并且运行web成功后,访问的页面不需要连接数据库,不牵扯到反射调用实体类就不会报错, 报错内容如下: [WARNING] org.springframework.web.util.Nested ...

  3. 【嵌入式开发板】8月终极暑促迅为Cortex-a9四核入门开发板

    核心板参数 尺寸 50mm*60mm 高度 连同连接器在内0.26cm CPU Exynos4412,四核Cortex-A9,主频为1.4GHz-1.6GHz 内存 1GB 双通道 DDR3(2GB  ...

  4. Hadoop 1.0 和 2.0 中的数据处理框架 - MapReduce

    1. MapReduce - 映射.化简编程模型 1.1 MapReduce 的概念 1.1.1 map 和 reduce 1.1.2 shufftle 和 排序 MapReduce 保证每个 red ...

  5. 算法实践——Twitter算法面试题(积水问题)的线性时间解法

    问题描述:在下图里我们有不同高度的挡板.这个图片由一个整数数组所代表,数组中每个数是墙的高度.下图可以表示为数组(2.5.1.2.3.4.7.2).假如开始下雨了,那么挡板之间的水坑能够装多少水(水足 ...

  6. java 16 -11 ArrayList存储自定义对象并增强for遍历

    需求:ArrayList存储自定义对象并遍历.要求加入泛型,并用增强for遍历. A:迭代器 B:普通for     C:增强for LinkedList,Vector,Colleciton,List ...

  7. Mac上安装node.js

    1.下载node for mac并一路默认安装 2.测试成功否 3.copy this file to test(save as javascript file) var http = require ...

  8. 堡垒机环境-jumpserver部署

    1:安装数据库 这里是提前安装,也可以不安装,在安装jumpserver主程序的时候,他会询问你是否安装 yum -y install ncurses-devel cmake echo 'export ...

  9. 认识实验室信息管理系统(LIMS)

    在当今互联网如日中天的大环境下,各种伴随着互联网的产物如p2p,o2o在如火如荼的进行着,吸引了大量的开发人员都涌向了这个行业,所有的技术似乎都在围绕着互联网发展,传统行业软件开发的人气和关注度就相形 ...

  10. 012医疗项目-模块一:统一异常处理器的设计思路及其实现(涉及到了Springmvc的异常处理流程)

    我们上一篇文章是建立了一个自定义的异常类,来代替了原始的Exception类.在Serice层抛出异常,然后要在Action层捕获这个异常,这样的话在每个Action中都要有try{}catch{}代 ...