哥们,我来贴上。我以前做的时候的代码。希望能帮的上你。这里是使用的threadlocal. 有详细的文字说明和备注.
- //当数据多的时候我们使用对象进行封装
- /**
- * 总结:
- * 我们这里其实是把封装多个数据的类做成了单例,然后在这个类的内部封装了一个ThreadLocal,
- * 在获取本类实例的静态方法中,首先是从当前线程获取是否有本类的实例存在,如果存在就返回,
- * 如果没有存在,就创建,然后把创建的本类的实例设置到当前的线程中。然后返回这个对象。使用
- * 这个样的封装。避免了保证了封装数据的对象在线程中的唯一性。保证了每个模块是从同一个对象
- * 身上获取的数据。
- */
- class ThreadScopeData{
- //我们先把这个类给做成单例的
- private ThreadScopeData(){}
- //别人不能创建这个类的实例对象但是可以通过我们提供的静态方法来获取这个类的实例对象
- public static ThreadScopeData getThreadInstance(){
- //饥汉模式存在一种线程安全的问题。就是说A线程调用了这个语句,要获取这个类的实例,但是
- //这个类的实例不存在,所以它就需要创建,还没有给这个引用赋值,这个时候B线程也进来了。
- //它判断对象也没有所以它也创建了。所以在内存里面就出现了两个这个类的实例。
- //这个时候了。我们就需要把这个方法做成互斥的。
- // return instance; //饱汉模式是直接返回创建好的实例对象
- //我们在调用这个方法的时候就直接去当前线程上取数据
- //取到的是于当前线程相关的实例对象
- ThreadScopeData instance=myThreadData.get(); //获取与本线程相关的实例对象
- //我们把当前这个类的实例对象,因为这个类是单例的所以只能有一个实例对象,我们把它给添加到
- //到当前线程上去了。就意味着在当前线程中只会有一个实例对象的存在。这样在当前线程上的所有模块
- //拿到的数据都是同一份,因为我们的这个方法最开始的语句是从当前线程中获取实例对象,如果对象
- //存在就返回对象如果不存在就创建对象然后设置到线程中。A线程在没有获取到实例对象创建的时候,
- //还没有赋值。B线程也没有获取到。它也创建。这个时候我们的方法是可以不用互斥的。因为它们是从不
- //同的线程中获取的实例对象。A线程不会影响到B线程。B线程也不会影响到A线程。
- if(instance==null){ //在调用这个方法的时候,如果对象存在就直接返回
- //如果对象不存在就创建这个对象然后返回这个对象的实例
- instance=new ThreadScopeData();
- //如果对象存在就直接返回如果不存在就创建这个对象给设置到当前线程上去。
- myThreadData.set(instance);
- }
- return instance;
- }
- //我们这么来做,我们把当前创建的对象的实例给设置到当前的线程中
- private static ThreadLocal<ThreadScopeData> myThreadData=new ThreadLocal<ThreadScopeData>();
-
- //顺便演示一下单例中的两种模式
- //这是饱汉模式:对象直接创建创建好的。它是随着类的加载而加载
- // private static MyThreadLocalScopeData instance=new MyThreadLocalScopeData();
- //这里是饥汉模式:对象引用先创建但是赋的是空值
- // private static MyThreadLocalScopeData instance=null;
-
- 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;
- }
- }
复制代码 |