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』带你从数模小白成为 ...
随机推荐
- 关于在Struts2框架下实现文件的上传功能
struts2的配置过程 (1)在项目中加入jar包 (2)web.xml中filter(过滤器)的配置 <?xml version="1.0" encoding=" ...
- ReSharper 8.0.2000.2660
user:dobit sn:G/YgFyekI7EL0oBc5YBWKI5WCi3pwXWP 下载地址
- jQuery的deferred对象详解(一)
最近一段时间,都在研究jquery里面的$.Deffered对象,几天都搞不明白,其中源码的运行机制,网上查找了相关的资料,<jQuery的deferred对象详解>阮一峰老师的文章,里面 ...
- Kinect For Windows V2开发日志六:人体的轮廓的表示
Kinect中带了一种数据源,叫做BodyIndex,简单来说就是它利用深度摄像头识别出最多6个人体,并且用数据将属于人体的部分标记,将人体和背景区别开来.利用这一特性,就可以在环境中显示出人体的轮廓 ...
- 【java.math.BigInteger】常用函数
1. /* 返回此BigInteger的函数正负号. 此方法返回-1,0或1作为此BigInteger的值对应是负,零或正数. */ java.math.BigInteger.signum(BigIn ...
- hdu-5695 Gym Class(贪心+拓扑排序)
题目链接: Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 学习笔记2:前端PS切图
前端PS切图 一.Photoshop的界面设置 二.Photoshop的基本操作 三.Photoshop的传统切图 四.Photoshop的精准切图 五.Photoshop的扩展知识 视频学习:htt ...
- 【ASP.NET基础】客户端、服务器端的数据验证 + CKEditer
1, 客户端 用Javascript进行验证,直接提示用户输入的数据是否符合规范,是否合法. 这样体验行比较好,客户端立即就可以得到反馈,而且减少了服务器端的数据交互. 这样前端数据验证并不是很安全, ...
- [转载]JSON序列化与反序列化
转载:http://www.cnblogs.com/ejiyuan/archive/2010/04/09/1708084.html 方法一:引入System.Web.Script.Serializat ...
- LINQ to SQL 语句(3) 之 Count/Sum/Min/Max/Avg
LINQ to SQL 语句(3) 之 Count/Sum/Min/Max/Avg [1] Count/Sum 讲解 [2] Min 讲解 [3] Max 讲解 [4] Average 和 Agg ...