ThreadLocal实现线程范围的共享变量

 

package com.itcast;

import java.util.Random;

public class ThreadScopeShareMoney {

	/**
	 * @param args
	 */
	private static int money = 0;
	private static ThreadLocal<Integer> threadlocal = new ThreadLocal<Integer>();   // ThreadLocal线程局部变量
	public static void main(String[] args) {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					int money = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()
							+ " put money: " + money);
					threadlocal.set(money);
					MyThreadScopeData.getThreadInstance().setName("name" + money);  //  在线程当中添加数据
					MyThreadScopeData.getThreadInstance().setMoney(money);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

	static class A {
		public void get(){
			int data = threadlocal.get();	//从当前的线程取出数据		
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " get data :" + data);
			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " getData: " + myData.getName() + "," +
					myData.getMoney());			
		}		
	}

	static class B{
		public void get(){
			int data = threadlocal.get();	//从当前的线程取出数据			
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " get data :" + data);
			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " getMyData: " + myData.getName() + "," +
					myData.getMoney());			
		}		
	}
}

class MyThreadScopeData {
	private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
	
	private MyThreadScopeData(){
		
	}
	public static MyThreadScopeData getThreadInstance(){       //懒汉模式
		MyThreadScopeData instance = map.get();
		if(instance==null){
			instance = new MyThreadScopeData();
			map.set(instance);
		}
		return instance;
	}
	private String name;
	private int money;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}

}

 

运行结果为:
Thread-0 put money: -1153260093
Thread-1 put money: 264490866
A from Thread-0 get data :-1153260093
A from Thread-1 get data :264490866
A from Thread-0 getData: name-1153260093,-1153260093
A from Thread-1 getData: name264490866,264490866
B from Thread-1 get data :264490866
B from Thread-0 get data :-1153260093
B from Thread-1 getMyData: name264490866,264490866
B from Thread-0 getMyData: name-1153260093,-1153260093
 

实验步骤:
1.先在MyThreadLocalData类中定义一个访问权限为public的ThreadLocal类型的变量x,直接对这个x进行读写操作;
2.将变量x的访问权限定义为private, MyThreadLocalData上定义相应的set和get方法对向变量x中存储和检索数据;
3.将MyThreadLocalData类自身变成一个具有业务功能的对象,每个线程仅能有该类的一个实例对象,即对于不同的线程来说,MyThreadLocalData.getMyData静态方法拿到的对象都不相同,但对于同一个线程来说,不管调用MyThreadLocalData.getMyData多少次和在哪里调用,拿到的都是同一个MyThreadLocalData对象。MyThreadLocalData封装成具有业务功能的对象,然后设计getMyData方法的定义,最后定义getMyData方法要操作的ThreadLocal变量和编写具体的代码。

 

 

     ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值。在线程结束时可以调用ThreadLocal.clear()方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。

      总结:一个ThreadLocal代表一个变量,故其中里只能放一个数据,你有两个变量都要线程范围内共享,则要定义两个ThreadLocal对象。如果有一个百个变量要线程共享呢?那请先定义一个对象来装这一百个变量,然后在ThreadLocal中存储这一个对象。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值