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』带你从数模小白成为 ...
随机推荐
- 【MYSQL】常用命令备忘录
source 不接路径时,查找文件的路径是执行mysql命令时的路径 接路径时,使用路径+filename [root@wordpressserver mysql]# vi demo.mysql [r ...
- Git 对象
Git 提供了很多方法可以方便地访问 Git 库中的对象: ♦ 采用不分的 SHA1 哈希值.不必把 40 位的哈希值写全,只采用开头的部分(4 位以上),只要不与现有的其他哈希值冲突即可. ♦ 使用 ...
- ASCII码表 char(9),char(10),char(13)等
char(9) 水平制表符 char(10) 换行 char(13) 回车 测试ASCII码的方法: 在记事本中,按住ALT键,同时用小键盘输入十进制的ASCII码,然后松手,就可以看到效果了! ...
- Java Lock
JVM中的另一种锁Lock的实现.与synchronized不同的是,Lock完全用Java写成,在java这个层面是无关JVM实现的.在java.util.concurrent.locks包中有很多 ...
- Problem:Minesweeper Master
Google code jam Qualification Round 2014 题目链接:https://code.google.com/codejam/contest/dashboard?c=29 ...
- oralce之存储过程
一:--循环向表emp中插入数据 declare maxnumber ; v_count number; begin v_count :; ..maxnumber LOOP v_count :; in ...
- Speex回声消除代码分析
先说明下,这里的代码流程是修改过的Speex流程,但与Speex代码差异不大,应该不影响阅读. (1)用RemoveDCoffset函数进行去直流 (2)远端信号预加重后放入x[i+frame_s ...
- poj 3728 The merchant 倍增lca求dp
题目: zdf给出的题目翻译: 从前有一个富饶的国度,在这里人们可以进行自由的交易.这个国度形成一个n个点的无向图,每个点表示一个城市,并且有一个权值w[i],表示这个城市出售或收购这个权值的物品.又 ...
- 转: adroid音视延迟 10ms的原因与解答
https://github.com/hehonghui/android-tech-frontier/blob/master/issue-9/Android%2010ms%E9%97%AE%E9%A2 ...
- android chrome 不支持 audio/video的autoplay 属性
在chrome 浏览器中输入:chrome://flags,找到"播放媒体时的手势要求",停用就可以了.