本例充分演示了ThreadLocal在多线程环境下,与线程绑定后的数据操作是完全隔离的!
放心使用ThreadLocal吧!千万记得用完之后要remove!
package thread; import java.util.Date; import java.util.Random; /** * 线程范围内的变量,每个线程都有自己的一份数据,换不干扰 * * 原理: * ThreadLocal类中通过Map<Thread.currentThread(), Object>实现数据与线程绑定的! * Map的key就是线程自己,所以每个线程都能拿到属于自己的那份数据 * */ public class ThreadLocalScopeData { private static ThreadLocal<TreadLocalScopeData> threadLocal = new ThreadLocal<TreadLocalScopeData>(); private ThreadLocalScopeData() {} //此方法不需要同步 public static TreadLocalScopeData getThreadLocalBinding() { TreadLocalScopeData instance = threadLocal.get(); if(instance==null) { instance = new TreadLocalScopeData(); threadLocal.set(instance); } return instance; } //============================================= Object data1; Object data2; // define more data binding to thread public TreadLocalScopeData data1(Object data1) { this.data1 = data1; return this; } public TreadLocalScopeData data2(Object data2) { this.data2 = data2; return this; } //finally remove threadLocal variable public void remove() { threadLocal.remove(); } //************************************************** //Test public static void main(String[] args) { for(int i=0;i<10;i++) { new Thread(new Runnable() { public void run() { ThreadLocalScopeData.justSet(); ThreadLocalScopeData.justGet("before remove"); //attempt to visit threadLocal data after removed TreadLocalScopeData.getThreadLocalBinding().remove(); TreadLocalScopeData.justGet("after remove"); } }).start(); } } public static void justSet() { TreadLocalScopeData treadLocalScopeData = TreadLocalScopeData.getThreadLocalBinding(); String data1Val = new Date() +", so easy!"; int data2Val = new Random().nextInt(); System.out.println(Thread.currentThread().getName()+" set: " + data1Val + ", " + data2Val); treadLocalScopeData.data1(data1Val).data2(data2Val); try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { return; } } public static void justGet(String when) { TreadLocalScopeData treadLocalScopeData = TreadLocalScopeData.getThreadLocalBinding(); System.out.println(Thread.currentThread().getName()+" get "+ when +":" + treadLocalScopeData.data1 + ", " + treadLocalScopeData.data2); try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { return; } } }