线程范围内的共享变量,通俗的说就是指:特定的线程对应特定的数据,不会因为对象的变化数据而改变。
ThreadLocal 的使用方便我们对不同的线程管理不同的数据,而且能够很好的对单例进行复用,因为我们通常不同的数据对象对应不同的单例进行保存,如果一旦分类数据过多,那么我们得创建大量的单例进行保存。然而ThreaLocal能够做到单例的复用。下面请看代码
public class ThreadScopShareData { static ThreadLocal<Integer> x= new ThreadLocal<Integer>(); // private static int data = 0; // private static Map<Thread,Integer> threadData = new HashMap<Thread, Integer>();//此处为了相同的线程能够拿到共同的数据 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 data = new Random().nextInt(); System.out.println(Thread.currentThread().getName()+"has put data: "+data); x.set(data);//数据存入到当前线程中 // threadData.put(Thread.currentThread(),data); MyThreadScopeData.getInstance().setName("name"+data);//本线程对应的实例 MyThreadScopeData.getInstance().setAge(data); new A().get(); new B().get(); } }).start(); } } static class A{ public int get(){ // int data = threadData.get(Thread.currentThread()); int data = x.get();//获取当前线程数据 System.out.println("A from"+Thread.currentThread().getName()+"get data: "+data); MyThreadScopeData mydata = MyThreadScopeData.getInstance(); System.out.println("A from"+Thread.currentThread().getName()+"get Mydata: "+mydata.getAge()+","+mydata.getName()); return data; } } static class B{ public int get(){ int data = x.get();//获取当前线程数据 // int data = threadData.get(Thread.currentThread()); System.out.println("B from"+Thread.currentThread().getName()+"get data: "+data); MyThreadScopeData mydata = MyThreadScopeData.getInstance(); System.out.println("B from"+Thread.currentThread().getName()+"get Mydata: "+mydata.getAge()+","+mydata.getName()); return data; } } } class MyThreadScopeData{ // private static MyThreadScopeData instance=null; private MyThreadScopeData(){ } public static /*synchronized*/ MyThreadScopeData getInstance(){//加同步锁是为了防止出现多个对象 MyThreadScopeData instance = map.get();//此处可以针对不同线程new 对应的单例,提高代码的复用 if(instance ==null){ instance = new MyThreadScopeData(); map.set(instance); } return instance; } private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>(); private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
该代码的运行结果为
可见对象的不同,只要是线程一样数据就一样。
这对于我们在处理并发访问上给出了一些提示。
时间: 2024-10-18 20:44:30