首先来看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. 原始的2文件的makefile错误

    从来没系统的看过makefile文档,平时属于复制模板,用完即忘,下午尝试按自己的理解写一个最简单的makefile,含2个.c文件,1个.h文件,费了个把小时,参考别人的文章才弄出来,特记录. ma ...

  2. SQL SERVER 2012 使用订阅发布同步数据库

    软件做大了,客户就多了,一个数据库服务器是远远不够的,当有一台数据服务器卦掉,那整个系统就会崩溃,所以必须考虑到数据库的自动同步与备份,当一台数据库服务 器宕机,自然就有用一台数据服务器启动起来保证整 ...

  3. DW Basic Knowledge2

    DW的元数据是指除去数据本身之外的所有信息. 围绕DBMS方面的元数据可以描述为表定义,分区设置,索引视图定义,以及DBMS级安全方面的特权 与授权等内容. 在任何场合下,ODS要么是一个处在OLTP ...

  4. TFS 2013”无法移除仍为团队管理员身份的标识”

    由于开发人员的工作变动,在TFS 2013的日常维护中,经常需要将已经离开团队的成员账户移除出本团队项目. 一.将用户从团队成员中移除 一般情况下,只需要在团队项目的控制面板界面(控制面板>Co ...

  5. SharpDX之Direct2D教程II——加载位图文件和保存位图文件

    本系列文章目录: SharpDX之Direct2D教程I——简单示例和Color(颜色) 绘制位图是绘制操作的不可缺少的一部分.在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再 ...

  6. shell script 学习笔记-----标准输出

    1.将标准输出(stdout)和标准错误输出(stderr)分别重定向到两个不同的文件 其中符号'>'默认将标准输出重定向,意思和'1>'相同,‘2>'表示重定向标准错误输出,数字1 ...

  7. POJ-1979 Red and Black(DFS)

    题目链接:http://poj.org/problem?id=1979 深度优先搜索非递归写法 #include <cstdio> #include <stack> using ...

  8. Linux搭建PHP+MySQL+Apache环境

    环境: CentOS 6.4 MySQL详细安装可参考:http://www.cnblogs.com/yangxia-test/archive/2012/11/12/2766237.html Apac ...

  9. js原生选项卡(包含无缝滚动轮播图)一

    原生js选项卡的几种写法,整片文章我会由简及难的描述几种常用的原生选项卡的写法: Improve little by little every day! 1>基本选项卡: 思路:循环中先清除再添 ...

  10. tp登录方法

    先根据输入的名字检测是否存在数据表中,如果有继续进一步验证密码,除了select(),find()可以查询数据外,还可以用getByXxx()指定数据表字段查询, 比如数据表有username字段,就 ...