ThreadLocal模式探索
一、首先,ThreadLocal模式使共享数据能多个线程被访问,每个线程访问的只是这个数据的副本,线程之间互不影响。
例子1:
package Thread2; public class Counter { //新建一个静态的ThreadLocal变量,并通过get方法将其变为一个可访问的对象
private static ThreadLocal<Integer> counterContext = new ThreadLocal<Integer>(){
protected synchronized Integer initialValue(){
return 10;
}
}; //通过静态的get方法访问ThreadLocal中存储的值
public static Integer get(){
return counterContext.get();
} //通过静态的set方法将变量值设置到ThreadLocal中
public static void set (Integer value){
counterContext.set(value);
}
//封装业务逻辑,操作存储于ThreadLocal中的变量
public static Integer getNextCounter(){
counterContext.set(counterContext.get()+1);
return counterContext.get();
}
}
package Thread2; 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());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }
package Thread2; public class Test2 { public static void main(String[] args) throws Exception{ ThreadLocalTest testThread1 = new ThreadLocalTest();
ThreadLocalTest testThread2 = new ThreadLocalTest();
ThreadLocalTest testThread3 = new ThreadLocalTest(); testThread1.start();
testThread2.start();
testThread3.start();
}
}
运行结果:
Thread[Thread-2 ], counter = 11
Thread[Thread-0 ], counter = 11
Thread[Thread-1 ], counter = 11
Thread[Thread-1 ], counter = 12
Thread[Thread-2 ], counter = 12
Thread[Thread-0 ], counter = 12
Thread[Thread-2 ], counter = 13
Thread[Thread-1 ], counter = 13
Thread[Thread-0 ], counter = 13
例子2:
package Thread; class AStub {
public void output() {
LocalThreadScopeData data = LocalThreadScopeData.getInstance();
if (data != null)
System.out.println("AStub:" + Thread.currentThread().getName()
+ ": data name = " + data.getName() + "age= "
+ data.getAge());
}
} package Thread; class BStub {
public void output() {
LocalThreadScopeData data = LocalThreadScopeData.getInstance();
if (data != null)
System.out.println("BStub:" + Thread.currentThread().getName()
+ ": data name = " + data.getName() + "age= "
+ data.getAge());
}
} package Thread; class LocalThreadScopeData {
// 把对象与当前线程绑定
private static ThreadLocal<LocalThreadScopeData> mThreadLocal = new ThreadLocal<LocalThreadScopeData>();
// 当前实例
private static LocalThreadScopeData instance = null; // 单例模式
public static LocalThreadScopeData getInstance() {
instance = mThreadLocal.get();
if (instance == null) {
instance = new LocalThreadScopeData();
mThreadLocal.set(instance);
}
return instance;
} private String name;// 姓名
private Integer age;// 年龄 public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
}
} package Thread;
import java.util.Random; public class ThreadTest { public static void main(String argv[]) { // 启动俩个线程
for (int i = 0; i < 2; i++) { new Thread() { public void run() {
int value = new Random().nextInt(10);
LocalThreadScopeData data = LocalThreadScopeData
.getInstance();
data.setAge(value);
data.setName("name" + value);
System.out.println("main:" + Thread.currentThread().getName()
+ "name = name " + value); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
new AStub().output();
new BStub().output();
}
}.start();
}
}
}
运行结果:
main:Thread-0name = name 5
main:Thread-1name = name 0
AStub:Thread-0: data name = nullage= null
AStub:Thread-1: data name = name0age= 5
BStub:Thread-0: data name = nullage= null
BStub:Thread-1: data name = name0age= 5
例子3:
package Thread4; public class Student {
private int age = 0; //年龄 public int getAge() {
return this.age;
} public void setAge(int age) {
this.age = age;
}
} package Thread4; import java.util.Random; public class ThreadLocalDemo implements Runnable {
//创建线程局部变量studentLocal,在后面你会发现用来保存Student对象
private final static ThreadLocal studentLocal = new ThreadLocal(); public static void main(String[] agrs) {
ThreadLocalDemo td = new ThreadLocalDemo();
Thread t1 = new Thread(td, "a");
Thread t2 = new Thread(td, "b");
t1.start();
t2.start();
} public void run() {
accessStudent();
} /**
* 示例业务方法,用来测试
*/
public void accessStudent() {
//获取当前线程的名字
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running!");
//产生一个随机数并打印
Random random = new Random();
int age = random.nextInt(100);
System.out.println("thread " + currentThreadName + " set age to:" + age);
//获取一个Student对象,并将随机数年龄插入到对象属性中
Student student = getStudent();
student.setAge(age);
System.out.println("thread " + currentThreadName + " first read age is:" + student.getAge());
try {
Thread.sleep(500);
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge());
} protected Student getStudent() {
//获取本地线程变量并强制转换为Student类型
Student student = (Student) studentLocal.get();
//线程首次执行此方法的时候,studentLocal.get()肯定为null
if (student == null) {
//创建一个Student对象,并保存到本地线程变量studentLocal中
student = new Student();
studentLocal.set(student);
}
return student;
}
}
运行结果:
b is running!
thread b set age to:31
a is running!
thread a set age to:45
thread b first read age is:31
thread a first read age is:45
thread b second read age is:31
thread a second read age is:45
参考:struts2设计模式,
http://lavasoft.blog.51cto.com/62575/51926/
http://blog.csdn.net/com360/article/details/6789367
ThreadLocal模式探索的更多相关文章
- 【Java EE 学习 19】【使用过滤器实现全站压缩】【使用ThreadLocal模式解决跨DAO事务回滚问题】
一.使用过滤器实现全站压缩 1.目标:对网站的所有JSP页面进行页面压缩,减少用户流量的使用.但是对图片和视频不进行压缩,因为图片和视频的压缩率很小,而且处理所需要的服务器资源很大. 2.实现原理: ...
- ThreadLocal模式的核心元素
首先来看ThreadLocal模式的实现机理:在JDK的早期版本中,提供了一种解决多线程并发问题的方案:java.lang.ThreadLocal类.ThreadLocal类在维护变量时,世纪使用了当 ...
- 【深入比较ThreadLocal模式与synchronized关键字】
[深入比较ThreadLocal模式与synchronized关键字]ThreadLocal模式与synchronized关键字都是用于处理多线程并发访问变量的问题.只是两者处理问题的角度和思路不同. ...
- ThreadLocal模式的原理
在JDK的早期版本中,提供了一种解决多线程并发问题的方案:java.lang.ThreadLocal类.ThreadLocal类在维护变量时,实际使用了当前线程(Thread)中的一个叫做Thread ...
- ThreadLocal模式与synchronized关键字的比较
ThreadLocal模式与synchronized关键字都是用于处理多线程并发访问变量的问题.只是两者处理问题的角度和思路不同. 1)ThreadLocal是一个Java类,通过对当前线程(Thre ...
- Struts2中的设计模式----ThreadLocal模式
http://www.cnblogs.com/gw811/archive/2012/09/07/2675105.html 设计模式(Design pattern):是经过程序员反复实践后形成的一套代码 ...
- 【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式
[转]Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式 博客分类: 企业应用面临的问题 java并发编程 Struts2的线程安全ThreadLocal模式St ...
- 浅谈ThreadLocal模式
一.前言: ThreadLocal模式,严格意义上不是一种设计模式,而是java中解决多线程数据共享问题的一个方案.ThreadLocal类是java JDK中提供的一个类,用来解决线程安全问题,并不 ...
- Python小白的数学建模课-A1.2021年数维杯C题(运动会优化比赛模式探索)探讨
Python小白的数学建模课 A1-2021年数维杯C题(运动会优化比赛模式探索)探讨. 运动会优化比赛模式问题,是公平分配问题 『Python小白的数学建模课 @ Youcans』带你从数模小白成为 ...
随机推荐
- 基于 Equinox 的 OSGi Console 的研究和探索
自定制 OSGi Console 进行组建和服务生命周期管理模块化编程的好处已经很好地被理解了约 40 年,但在 OSGi 之前,开发人员不得不自己发明模块化设计和系统.随着软件应用体系结构的不断发展 ...
- swift 委托代理传值
委托代理 1.定义个协议 2.声明一个委托代理 3.指定委托代理,调用委托实现的协议方法 4实现LoadingDelegate协议 代码如下: import UIKit //1.定义个协议 proto ...
- Jmeter参数化的4种方法
用Jmeter测试时包含两种情况的参数,一种是在url中,一种是请求中需要发送的参数. URL中的参数,如:http://blog.da-fang.com/index.php/2010/06/01/j ...
- 【Warshall_Floyd】
模板: /* Problem: 任意两点间的最短路 Tips : 可以处理边时负数的情况. 判断图中是否有负圈,只需检查d[i][j]是负数的顶点i就可以. 复杂度 : O(n^3) */ #incl ...
- hihocoder 1082 然而沼跃鱼早就看穿了一切(字符串替换)
时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 fjxmlhx每天都在被沼跃鱼刷屏,因此他急切的找到了你希望你写一个程序屏蔽所有句子中的沼跃鱼(“marshtomp”,不区 ...
- Sharepoint 2013 安装部署系列篇 第三篇 -- 安装和配置网络负载均衡在前端web服务器
第一部分 系统集群安装 第二部分 SQL集群安装 第四部分 安装和配置sharepoint 场(三层拓扑部署) 接下来一步一步开始配置NLB吧, 以下开始讲解如何配置NLB集群作为sharepoint ...
- MySql运算符
算数运算符 加(+).减(-).乘(*).除(/).求余(%) 比较运算符 大于(>).小于(<).等于(=).大于等于(>=).小于等于(<=).不等于(!= 或者 < ...
- c#中文件上传(1)
* * ;//3M picPath = Server.MapPath("........."); HttpFileCollection postfile = Context.Req ...
- 基础面试题——Javascript
1.介绍js的基本数据类型 Undefined.Null.Boolean.Number.String 2.js有哪些内置对象? 数据封装类对象:Object.Array.Boolean.Number ...
- MVC基础知识-持续更新....
1.如何在自动生成的视图中显示需要的字段名称: 在相应的定义字段中添加Display,例如: [Display(Name = "用户名:")] public string User ...