@lzb1096101803
2016-03-15T09:38:17.000000Z
字数 1192
阅读 361
电话面试
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的(看下面的代码Session示例)。各个线程中访问的是不同的对象。
另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象 的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。
通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。
如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。
public static final ThreadLocal<session> sessions =
new ThreadLocal<session>();
public static Session currentSession() throws HibernateException {
Session s = sessions.get();
//如果从当前线程变量中获取的session为空,直接open一个session放到当前线程变量中。
//值得注意的是,这里的session引用s是在方法体内声明的,属于局部变量,其他线程根本访问不到。
//就是说,这里的session s本身就不是一个共享对象,本身就是当前线程独一无二的存在。
//下一个线程来的时候,从sessions.get()拿出来的session s又是下一个线程的线程变量中的值。如果为空,同样创建。
//所以,session在线程变量内部还是外部都是没有和任何线程共享的。
if(s == null) {
s = sessionFactory.openSession();
sessions.set(s);
}
Java的ThreadLocal**不是设计用来解决多线程安全问题的,事实证明也解决不了,共享变量a还是会被随意更改。ThreadLocal无能为力。所以,一般用ThreadLocal都不会将一个共享变量放到线程的ThreadLocal中。一般来讲,存放到ThreadLocal中的变量都是当前线程
本身就独一无二的一个变量。其他线程本身就不能访问,存到ThreadLocal中只是为了方便在程序中同一个线程之间传递这个变量。 所以,ThreadLocal和解决线程安全没有关系**。