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』带你从数模小白成为 ...
随机推荐
- C#读取Word模板替换相应的字符串(标签)生成新的Word
在平常工作中,生成word的方式主要是C#读取html的模板文件处理之后保存为.doc文件,这样的好处是方便,快捷,能满足大部分的需求.不过有些特殊的需求并不能满足,如要生成的Word为一个表格,只是 ...
- OC 和 swift 小结
1 什么是 OC 语言? OC 语言即面向对象语言,它扩展了 ANSI C 语言,将 SmallTalk 式的消息传递机制加入到 ANSI C 中.它是苹果 OS 和 iOS 以及相关的 API,Co ...
- Scoket
1.Socket 几个常用的名词 IPC—>Inter Process Communication,进程间通信 socket —> 套接字 TCP—>Transmission Con ...
- 典型的字符串处理代码(page50)
Page50: public class TypicalString{//典型的字符串处理代码 public static boolean isPlalindrom(String s){//判断字符串 ...
- freeCodeCamp:Sorted Union
写一个 function,传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组. 换句话说,所有数组中的所有值都应该以原始顺序被包含在内,但是在最终的数组中不包含重复值. 非重 ...
- 第一个过滤器Filter
过滤器实现Filter接口javax.servlet.Filter package com.henau.example; import java.io.IOException; import java ...
- Ionic Android开发环境搭建 下
上篇 Ionic 安装完成了,由于要开发Android,所以必不可少需要继续搭建Android开发环境. 首先,下载并安装JDK.然后配置一下环境变量. 接着,下载并安装Android SDK.下载过 ...
- PHP和CS的引用传值
PHP的引用传值 function change_value($num){ $num+=2; } $age = 3; change_value(&$age); echo $age; CS的引用 ...
- LAMP+Proftpd+数据迁移
on Centos 6.5 64bit minimal 安装mysql [root@ftp ~]# yum install -y mysql mysql-server mysql-devel --安 ...
- C#中的 具名参数 和 可选参数
具名参数 和 可选参数 是 C# framework 4.0 出来的新特性. 一. 常规方法定义及调用 public void Demo1(string x, int y) { //do someth ...