首先来看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. Hibernate占位符?和:及JPA

    小结一下hibernate占位符. 1.最常见的?占位符. String hql = "select a from Apple a where a.color=? a.weight>? ...

  2. [麦先生]Laravel SQL语句记录方式

    打印sql语句,直接在你执行SQL语句后输出 方法一: $queries = DB::getQueryLog(); $a = end($queries); $tmp = str_replace('?' ...

  3. 1.素数判定(如何输出\n,\t,不用关键字冲突)

    题目描述 Description 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数. 素数在数论中有着很重要的地位.比1大但不是素数的数称为合数.1和0既非素数也 ...

  4. 边工作边刷题:70天一遍leetcode: day 76

    Count Univalue Subtrees 要点:检测条件比较有意思:因为可能的情况比较多,只要违反了任意一条就return False,所以可以只考虑False的情况,最后return True ...

  5. UESTC 915 方老师的分身II --最短路变形

    即求从起点到终点至少走K条路的最短路径. 用两个变量来维护一个点的dis,u和e,u为当前点的编号,e为已经走过多少条边,w[u][e]表示到当前点,走过e条边的最短路径长度,因为是至少K条边,所以大 ...

  6. 云盘WEB资料下载链接

    入门三板斧:http://www.cnblogs.com/jikey/p/3613082.html 入门看这个:http://pan.baidu.com/s/1pJqJvAV 入门JS视频:http: ...

  7. Android网络之数据解析----SAX方式解析XML数据

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  8. 当文本溢出包含的元素时加省略号之text-overflow

    text-overflow是css3的属性,用来处理文本溢出,默认裁剪处理,text-overflow属性只能用于block和inline-block元素,内联的和box,flex-flow:colu ...

  9. Spring2.5与JDK8的集成问题

    Spring2.5不支持JDK8及其以上的版本,因为有一段校验JDK版本的代码,当JDK版本大于1.7之后,会识别成JDK1.4之前的.会报版本太低的错误. /* * Copyright 2002-2 ...

  10. 【原创】有关Silverlight中“DataGrid中单元格动态绑定ComboBox单击时数据项莫名被清除 ”的解决方案及思路。

    今天上班遇到一个很古怪的问题,搞了半天愣是没找到原因.是这样的,在Datagrid中有绑定一个ComboBox列,其不包含在 model数据中,而是单独在LoadingRow事件中去 从数据库拿数据绑 ...