ThreadLocal实现线程范围的共享变量
2016-09-19 00:42
489 查看
ThreadLocal实现线程范围的共享变量
1.ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,
多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另一
分数据。
2.每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加了一
条记录,key分别是各自的线程,value是各自的set方法进去的值,在线程结束时可以
调用ThreadLocal()方法,这样会更快释放内存,不调用也可以,因为线程结束后也
可以自动释放相关的ThreadLocal变量
3.ThreadLocal的应用场景
(1)例如struts2的ActionContext,同一段代码被不同的线程调用时,该代码操作的数据是
每个线程各自的状态和数据,对于不同的线程来说,getContext方法拿到的对象都不
相同,对同一个线程来说,不管调用getContext方法多少次和在哪个模块中getContext
方法,拿到的都是同一个
(2) 银行转账包含一系列的操作,把转出账户的余额减少,把转入账户的余额增加,这两
个操作在同一个事务中进行,他们必须使用同一个数据库连接对象,而转入和转出分别
位于不同的账户对象的方法
直接用代码进行说明,创建三个线程,他们都访问了三个对象,第一个对象设置值,第二三个
对象取值,同一个线程设置的值,只能被相同的线程获取
public class ThreadScopeShareData {
private static int data =0 ;
private static Map<Thread,Integer> map = new HashMap<Thread,Integer> () ;
public static void main(String[]args) {
for (int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
pbulic void run() {
int data=new Random().nextInt();v
map.put(Thread.currentThread().getName(),data);
System.out.println(Thread.currentThread().getName() ++"put data" +data);
new A().get();
new B().get();
}
}).start();
}
}
staitc class A {
public void get() {
int data =map.get(Thread.currentThread().getName());
System.out.println("A from " +Thread.currentThread().getName() ++"put data" +data);
}
}
staitc class B{
public void get() {
int data =map.get(Thread.currentThread().getName());
System.out.println("B from " +Thread.currentThread().getName() ++"put data" +data);
}
}
现在用jdk提供ThreadLocal实现上面的效果:
public class ThreadScopeShareData {
private static int data =0 ;
pivate static ThreadLocal<Integer> myThreadLocal = new ThreadLocal<Integer>();
public static void main(String[]args) {
for (int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
pbulic void run() {
int data=new Random().nextInt();v
myThreadLocal.set(data);
System.out.println(Thread.currentThread().getName() ++"put data" +data);
new A().get();
new B().get();
}
}).start();
}
}
staitc class A {
public void get() {
int data =myThreadLocal.get();
System.out.println("A from " +Thread.currentThread().getName() ++"put data" +data);
}
}
staitc class B{
public void get() {
int data =myThreadLocal.get();
System.out.println("B from " +Thread.currentThread().getName() ++"put data" +data);
}
}
总结:myThreadLocal.set(data)存入与当前线程相关的数据,myThreadLocal.get()取出与当前线程相关的数据
一个ThreadLocal代表一个变量,故其中只能放入一个数据,你有两个变量都要线程范围内数据共享则要定
义两个ThreadLocal对象,容易想到的是把n个变量定义成一个实体,把这个实体作为一个变量存入ThreadLocal中
,我取就能取到n个变量了,其实这是一种很烂的写法,我都懒得写,还是实现以下,看下面的代码:
public
9897
class ThreadScopeShareData {
private static int data =0 ;
private static ThreadLocal<MyThreadScopData>myThreadLocalDate = new ThreadLocal<MtyThreadScopData>() ;
public static void main(String[]args) {
for (int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
pbulic void run() {
int data=new Random().nextInt();vv
MyThreadScopData myData = new MyThreadScopData();
MyThreadScopData.SetAge(data);
MyThreadScopData.setName(data+"");
myThreadLocalDate.set(myData);
System.out.println(Thread.currentThread().getName() ++"put data" +data);
new A().get();
new B().get();
}
}).start();
}
}
staitc class A {
public void get() {
MtyThreadScopData = myThreadLocalDate.get();
System.out.println("A from " +Thread.currentThread().getName() ++"put data" +MtyThreadScopData.getName()+"--"+MtyThreadScopData.getAge());
}
}
staitc class B{
public void get() {
MtyThreadScopData = myThreadLocalDate.get();
System.out.println("B from " +Thread.currentThread().getName() ++"put data" +MtyThreadScopData.getName()+"--"+MtyThreadScopData.getAge());
}
}
class myThreadScopData {
public int age ;
public Stirng nage ;
//set ,get 方法自己写
}
总结:我们用一个烂的方式实现把对象装进去,然后取出来,先让你认同用这种方式,下面我在用一个优雅
实现你就会认为我很牛
class myThreadScopData {
private MyThreadScopeData(){}
public staitc MyThreadScopeData getInstance(){
MyThreadScopeData instance = map.get();
if(instance == null){
instance =new MyThreadScopeData();
map.set(instance);
}
return instance;
}
private static ThreadLocal<MyThreadScopeData>map=new ThreadLocal<MyThreadScopeData>();
public int age ;
public Stirng nage ;
//set ,get 方法自己写
}
总结:用了类似单例模式的懒汉模式,调用getInstance()不存在线程
安全问题,两个线程没有共享一个实例,没必要考虑线程安全问题。
1.ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,
多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另一
分数据。
2.每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加了一
条记录,key分别是各自的线程,value是各自的set方法进去的值,在线程结束时可以
调用ThreadLocal()方法,这样会更快释放内存,不调用也可以,因为线程结束后也
可以自动释放相关的ThreadLocal变量
3.ThreadLocal的应用场景
(1)例如struts2的ActionContext,同一段代码被不同的线程调用时,该代码操作的数据是
每个线程各自的状态和数据,对于不同的线程来说,getContext方法拿到的对象都不
相同,对同一个线程来说,不管调用getContext方法多少次和在哪个模块中getContext
方法,拿到的都是同一个
(2) 银行转账包含一系列的操作,把转出账户的余额减少,把转入账户的余额增加,这两
个操作在同一个事务中进行,他们必须使用同一个数据库连接对象,而转入和转出分别
位于不同的账户对象的方法
直接用代码进行说明,创建三个线程,他们都访问了三个对象,第一个对象设置值,第二三个
对象取值,同一个线程设置的值,只能被相同的线程获取
public class ThreadScopeShareData {
private static int data =0 ;
private static Map<Thread,Integer> map = new HashMap<Thread,Integer> () ;
public static void main(String[]args) {
for (int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
pbulic void run() {
int data=new Random().nextInt();v
map.put(Thread.currentThread().getName(),data);
System.out.println(Thread.currentThread().getName() ++"put data" +data);
new A().get();
new B().get();
}
}).start();
}
}
staitc class A {
public void get() {
int data =map.get(Thread.currentThread().getName());
System.out.println("A from " +Thread.currentThread().getName() ++"put data" +data);
}
}
staitc class B{
public void get() {
int data =map.get(Thread.currentThread().getName());
System.out.println("B from " +Thread.currentThread().getName() ++"put data" +data);
}
}
现在用jdk提供ThreadLocal实现上面的效果:
public class ThreadScopeShareData {
private static int data =0 ;
pivate static ThreadLocal<Integer> myThreadLocal = new ThreadLocal<Integer>();
public static void main(String[]args) {
for (int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
pbulic void run() {
int data=new Random().nextInt();v
myThreadLocal.set(data);
System.out.println(Thread.currentThread().getName() ++"put data" +data);
new A().get();
new B().get();
}
}).start();
}
}
staitc class A {
public void get() {
int data =myThreadLocal.get();
System.out.println("A from " +Thread.currentThread().getName() ++"put data" +data);
}
}
staitc class B{
public void get() {
int data =myThreadLocal.get();
System.out.println("B from " +Thread.currentThread().getName() ++"put data" +data);
}
}
总结:myThreadLocal.set(data)存入与当前线程相关的数据,myThreadLocal.get()取出与当前线程相关的数据
一个ThreadLocal代表一个变量,故其中只能放入一个数据,你有两个变量都要线程范围内数据共享则要定
义两个ThreadLocal对象,容易想到的是把n个变量定义成一个实体,把这个实体作为一个变量存入ThreadLocal中
,我取就能取到n个变量了,其实这是一种很烂的写法,我都懒得写,还是实现以下,看下面的代码:
public
9897
class ThreadScopeShareData {
private static int data =0 ;
private static ThreadLocal<MyThreadScopData>myThreadLocalDate = new ThreadLocal<MtyThreadScopData>() ;
public static void main(String[]args) {
for (int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
pbulic void run() {
int data=new Random().nextInt();vv
MyThreadScopData myData = new MyThreadScopData();
MyThreadScopData.SetAge(data);
MyThreadScopData.setName(data+"");
myThreadLocalDate.set(myData);
System.out.println(Thread.currentThread().getName() ++"put data" +data);
new A().get();
new B().get();
}
}).start();
}
}
staitc class A {
public void get() {
MtyThreadScopData = myThreadLocalDate.get();
System.out.println("A from " +Thread.currentThread().getName() ++"put data" +MtyThreadScopData.getName()+"--"+MtyThreadScopData.getAge());
}
}
staitc class B{
public void get() {
MtyThreadScopData = myThreadLocalDate.get();
System.out.println("B from " +Thread.currentThread().getName() ++"put data" +MtyThreadScopData.getName()+"--"+MtyThreadScopData.getAge());
}
}
class myThreadScopData {
public int age ;
public Stirng nage ;
//set ,get 方法自己写
}
总结:我们用一个烂的方式实现把对象装进去,然后取出来,先让你认同用这种方式,下面我在用一个优雅
实现你就会认为我很牛
class myThreadScopData {
private MyThreadScopeData(){}
public staitc MyThreadScopeData getInstance(){
MyThreadScopeData instance = map.get();
if(instance == null){
instance =new MyThreadScopeData();
map.set(instance);
}
return instance;
}
private static ThreadLocal<MyThreadScopeData>map=new ThreadLocal<MyThreadScopeData>();
public int age ;
public Stirng nage ;
//set ,get 方法自己写
}
总结:用了类似单例模式的懒汉模式,调用getInstance()不存在线程
安全问题,两个线程没有共享一个实例,没必要考虑线程安全问题。
相关文章推荐
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量 代码示例
- 并发库应用之一 & ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围内共享变量
- Thread学习(八) ThreadLocal实现线程范围内的共享变量
- ThreadLocal实现线程范围的共享变量
- 【线程高新】——【ThreadLocal实现线程范围的共享变量】
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量-笔记整理4
- 黑马程序员--javaSE--ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围内共享变量和对象
- Java线程总结(四):ThreadLocal实现线程范围的共享变量
- 多线程篇四:ThreadLocal实现线程范围内变量共享
- 使用JDK提供的ThreadLocal实现线程范围的共享变量(类似于Map<Thread,Variable>)
- java-线程-用ThreadLocal类实现线程范围内的数据共享
- 多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)