[关闭]
@lzb1096101803 2016-03-15T09:38:17.000000Z 字数 1192 阅读 361

ThreadLocal

电话面试


首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的(看下面的代码Session示例)。各个线程中访问的是不同的对象。

另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象 的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。

通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。

如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。

  1. public static final ThreadLocal<session> sessions =
  2. new ThreadLocal<session>();
  3. public static Session currentSession() throws HibernateException {
  4. Session s = sessions.get();
  5. //如果从当前线程变量中获取的session为空,直接open一个session放到当前线程变量中。
  6. //值得注意的是,这里的session引用s是在方法体内声明的,属于局部变量,其他线程根本访问不到。
  7. //就是说,这里的session s本身就不是一个共享对象,本身就是当前线程独一无二的存在。
  8. //下一个线程来的时候,从sessions.get()拿出来的session s又是下一个线程的线程变量中的值。如果为空,同样创建。
  9. //所以,session在线程变量内部还是外部都是没有和任何线程共享的。
  10. if(s == null) {
  11. s = sessionFactory.openSession();
  12. sessions.set(s);
  13. }

Java的ThreadLocal**不是设计用来解决多线程安全问题的,事实证明也解决不了,共享变量a还是会被随意更改。ThreadLocal无能为力。所以,一般用ThreadLocal都不会将一个共享变量放到线程的ThreadLocal中。一般来讲,存放到ThreadLocal中的变量都是当前线程
本身就独一无二的一个变量。其他线程本身就不能访问,
存到ThreadLocal中只是为了方便在程序中同一个线程之间传递这个变量。 所以,ThreadLocal和解决线程安全没有关系**。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注