ThreadLocal实例2

来源:互联网 发布:秒赞网源码 编辑:程序博客网 时间:2024/06/05 10:58
**下面的例子中创建了两个线程,每个线程中存在多个局部变量。要使对象A和对象B输出当前线程的局部变量,需要使用ThreadLocal,多个变量放到一个实体类中实现。**package cn.threadLocal;import java.util.Random;import cn.threadLocal.ThreadLocalTest.A;import cn.threadLocal.ThreadLocalTest.B;public class ThreadLocalBean {    /**     * 将线程中的多个变量放到实体中     */    public static void main(String[] args) {        for(int i=0;i<2;i++){            new Thread(new Runnable(){                @Override                public void run() {               int  data=new Random().nextInt();               // 获取当前线程的student的对象,该对象已存入ThreadLocal中,变量互不打扰               student st=student.getInstance();               st.setAge(data);             System.out.println(Thread.currentThread().getName()+"has put data :"+data);                new A().get();                new B().get();                }            }).start();            }        }        static class A{            public void get(){             student st=student.getInstance();             System.out.println("A "+Thread.currentThread().getName()+"has put data :"+st.getAge());            }        }        static class B{            public void get(){                 student st=student.getInstance();                 System.out.println("b "+Thread.currentThread().getName()+"has put data :"+st.getAge());                }        }    }class student{    public static student getInstance(){        // 通过ThreadLocal的get()和set()函数得到的对象是改线程自己使用的对象,其他线程获取不到。每个线程使用不同的对象。        /**         * 本例中创建了两个线程,每个线程都有自己对应的student对象,不是同一个对象。         * 通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,         * 执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,         * ThreadLocal实例是作为map的key来使用的。         */        student instance=(student) local.get();        if(instance==null){            instance=new student();            local.set(instance);        }        return instance;    }    private static ThreadLocal local=new ThreadLocal();    private int age;    private String name ;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

二. 像ThreadLocal典型的应用莫过于Spring,Hibernate等框架中对于多线程的处理了.

下面来看一个hibernate中典型的ThreadLocal的应用private static final ThreadLocal threadSession = new ThreadLocal();  public static Session getSession() throws InfrastructureException {      Session s = (Session) threadSession.get();      try {          if (s == null) {              s = getSessionFactory().openSession();              threadSession.set(s);          }      } catch (HibernateException ex) {          throw new InfrastructureException(ex);      }      return s;  }  

可以看到在getSession()方法中,首先判断当前线程中有没有放进去session,如果还没有,那么通过sessionFactory().openSession()来创建一个session,再将session set到线程中,实际是放到当前线程的ThreadLocalMap这个map中,这时,对于这个session的唯一引用就是当前线程中的那个ThreadLocalMap(下面会讲到),而threadSession作为这个值的key,要取得这个session可以通过threadSession.get()来得到,里面执行的操作实际是先取得当前线程中的ThreadLocalMap,然后将threadSession作为key将对应的值取出。这个session相当于线程的私有变量,而不是public的。
显然,其他线程中是取不到这个session的,他们也只能取到自己的ThreadLocalMap中的东西。要是session是多个线程共享使用的,那还不乱套了。
- 列表内容

0 0