优缺点和使用注意事项:

 

/*
 * ThreadLocal 用于每一个线程都有一个次线程对应的副本。“以空间换时间”  占用内存,提高效率,节约处理时间,同时保证事物一致性
 * ThreadLocal防止内存泄漏的做法-->弱引用:WeakReference   extends WeakReference<ThreadLocal>
 * 弱引用:引用对象如果不工作,JVM扫面到此现象后会回收引用数值,节省内存
 * 强引用:eg String name = "zhangsan"; 一般对象如果不extends WeakReference都是强引用对象,特点是引用不消失,即使引用不工作了
 * 	    引用值仍旧存在内存,不会被JVM回收掉
 * 
 * 写代码建议: 使用ThreadLocal后,可以手动调用其remove()方法。
 * 
 */

 

 

 

业务要求

多线程下,实现线程内,多业务下数据共享使用; 实现线程之间数据彼此隔离

 

应用案例: 银行多人汇款

 

jdk1.5——ThreadLocal实现线程范围的共享变量_System


 

 

应用代码模拟---> 获取线程数据conn

public class ConnectionManager {

	
	private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
	
	private ConnectionManager(){}
	
	public static Connection getInstance(){
		try {
			Connection conn = threadLocal.get();
			if(conn == null){
				conn = DriverManager.getConnection("");//获取数据库连接对象
				threadLocal.set(conn);
			}
			return conn;
		} catch (SQLException e) {
			e.printStackTrace();
		
		}
		return null;
	}
	
}

 

 

 

 

 

 

要点: 使用map将线程和线程内公共数据绑定起来

 

代码1  自定义实现

package thread;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 1 实现线程范围内的数据共享
 * 2 实现线程之间的数据隔离
 * 3 使用map对象,将每个线程产生的数据放在map中,业务方法中 仅仅获取当前线程下的共享数据   达到2的目的
 * 
 * @author zm
 *
 *测试结果:
Thread-0 has put data 757103510
A from Thread-0 the data is: 757103510
B from Thread-0 the data is: 757103510
Thread-1 has put data -150123253
A from Thread-1 the data is: -150123253
B from Thread-1 the data is: -150123253
 */
public class ScopeShareDataInThread {

	// 
	public static int sharedata;
	public static Map map = new HashMap();
	
	public static void main(String[] args) {
		
		final Businness businness = new Businness();
		for(int i=0; i<2; i++) {
			new Thread(new Runnable(){
				@Override
				public void run() {
					sharedata = new Random().nextInt();
					System.out.println(Thread.currentThread().getName() + " has put data " + sharedata);
					map.put(Thread.currentThread(), sharedata);
					businness.business1(sharedata,map);
					businness.business2(sharedata,map);
				}
			}).start();
		}
		
	}

}

class Businness {
	// 业务1
	public void business1(int data,Map map){
		System.out.println("A from " + Thread.currentThread().getName() + " the data is: " + map.get(Thread.currentThread()));
	}
	// 业务2
	public void business2(int data,Map map){
		System.out.println("B from " + Thread.currentThread().getName() + " the data is: " + map.get(Thread.currentThread()));
	}
}

 

 

代码2 使用JDK提供的ThreadLocal类:

package thread;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 使用jdk提供的类来实现 线程内数据共享 线程间数据隔离
 * 
 * threadLocal.set(sharedata) 会把数据放在当前线程中
 * threadLocal.get() 回从当前线程中得到存放的数据
 * 
 * 其实 threadLocal = map.put(Thread.currentThread(), youdata);
 * 
 * 测试结果:
Thread-1 has put data 193003072
A from Thread-1 the data is: 193003072
B from Thread-1 the data is: 193003072
Thread-0 has put data -2012177886
A from Thread-0 the data is: -2012177886
B from Thread-0 the data is: -2012177886
 * @author zm
 *
 */
public class MyThreadLocal {

	// 
	public static ThreadLocal threadLocal = new ThreadLocal();
	
	public static int sharedata;
	
	
	
	public static void main(String[] args) {
		
		final Businness1 businness = new Businness1();
		for(int i=0; i<2; i++) {
			new Thread(new Runnable(){
				@Override
				public void run() {
					sharedata = new Random().nextInt();
					System.out.println(Thread.currentThread().getName() + " has put data " + sharedata);
					threadLocal.set(sharedata);
					businness.business1(threadLocal);
					businness.business2(threadLocal);
				}
			}).start();
		}
		
	}

}

class Businness1 {
	// 业务1
	public void business1(ThreadLocal threadLocal){
		System.out.println("A from " + Thread.currentThread().getName() + " the data is: " + threadLocal.get());
	}
	// 业务2
	public void business2(ThreadLocal threadLocal){
		System.out.println("B from " + Thread.currentThread().getName() + " the data is: " + threadLocal.get());
	}
}

 

 

脑图:

 

jdk1.5——ThreadLocal实现线程范围的共享变量_数据_02