锁定老帖子 主题:ThreadLocal-分析-总结
精华帖 (18) :: 良好帖 (7) :: 新手帖 (2) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-10-08
jiangzhouyun 写道 抄别人的吧 只有这段代码是“抄”的: 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; } 写这篇文章是由于之前淘宝电话面试时面试官提了一个问题,大概意思: “说说SpringMVC,Hibernate这些框架是怎么解决多线程的” 我在阅读Spring相关书籍的时候看到过ThreadLocal在他们中的重要性,但是那时还真的说不清楚,也就干脆没说。 回来觉得非常惭愧,所以仔细研究了一下,当然这个过程中参考很多网上的资料,如果你说部分有些相似,那我承认,但是抄那确实没有。 |
|
返回顶楼 | |
发表时间:2010-10-08
存在线程池时,再次启用这个线程时,threadlocal原来的值还在吗?ps: 可能跟线程池的实现有关.
|
|
返回顶楼 | |
发表时间:2010-10-08
xuyan2680 写道 存在线程池时,再次启用这个线程时,threadlocal原来的值还在吗?ps: 可能跟线程池的实现有关.
我不是很理解你的意思 ThreadTest test1 = new ThreadTest(10); ThreadTest test2 = new ThreadTest(20); ExecutorService executor = Executors.newFixedThreadPool(10); executor.execute(test1); //这个是你说的再次启用吗? executor.execute(test1); executor.shutdown(); 再次启用相当于从新开启一个线程,多个线程间是没有关系的,所以不存在“原来”的值 将代码稍微改下,如果还存在则会打印出“num exisit” if(n == null) { thLocal.set(num); } else { System.out.println("num exisit"); } |
|
返回顶楼 | |
发表时间:2010-10-10
有问题请教楼主:
ThreadLocalSample这个demo不是 启动两个线程来访问共享资源public Integer num; 吗? 论坛里面也有说: "ThreadLocal 不是用来解决共享对象的多线程访问问题的" 这怎么理解啊? |
|
返回顶楼 | |
发表时间:2010-10-10
明天的昨天 写道 有问题请教楼主:
ThreadLocalSample这个demo不是 启动两个线程来访问共享资源public Integer num; 吗? 论坛里面也有说: "ThreadLocal 不是用来解决共享对象的多线程访问问题的" 这怎么理解啊? demo中的num本身就不是ThreadLocal的,他就是普通的类变量,自然是线程共享的 num的存在只是为了在这句时起作用 引用 if(num != 20) { String s = thLocal2.get(); } 在DEBUG时可以看到如果num等于20的话,该线程的threadLocals:ThreadLocalMap中不会有thLocal2的记录,所以说明threadlocal是线程独立的。 也即-"ThreadLocal 不是用来解决共享对象的多线程访问问题的" |
|
返回顶楼 | |
发表时间:2010-10-10
mxdba321123 写道 明天的昨天 写道 有问题请教楼主:
ThreadLocalSample这个demo不是 启动两个线程来访问共享资源public Integer num; 吗? 论坛里面也有说: "ThreadLocal 不是用来解决共享对象的多线程访问问题的" 这怎么理解啊? demo中的num本身就不是ThreadLocal的,他就是普通的类变量,自然是线程共享的 num的存在只是为了在这句时起作用 引用 if(num != 20) { String s = thLocal2.get(); } 在DEBUG时可以看到如果num等于20的话,该线程的threadLocals:ThreadLocalMap中不会有thLocal2的记录,所以说明threadlocal是线程独立的。 也即-"ThreadLocal 不是用来解决共享对象的多线程访问问题的" 有一点我不太明白,在ThreadTest类中定义的2个ThreadLocal(thLocal,thLocal2),在初始化时会通过该线程的ThreadLocalMap把自身加入到该程中去,那么每个线程(test1,test2)的ThreadLocalMap应该都有这二个ThreadLocal吧,而且这二个ThreadLocal被定义为静态的,那么二个线程中引用的都是同样的ThreadLocal只不过key是每个线程吧?不知道这样理解对不对?望指教 |
|
返回顶楼 | |
发表时间:2010-10-10
最后修改:2010-10-10
错了,想了想,
ThreadLocalMap中key是每个ThreadLocal ThreadLocal是在get方法时被每个线程自己的ThreadLocalMap加入的 ThreadLocal根据每个线程来决定get()方法返回的值 |
|
返回顶楼 | |
发表时间:2010-10-11
这个帖子很详细
多学习下源码 就会很清楚了 |
|
返回顶楼 | |
发表时间:2010-10-11
mxdba321123 写道 xuyan2680 写道 存在线程池时,再次启用这个线程时,threadlocal原来的值还在吗?ps: 可能跟线程池的实现有关.
我不是很理解你的意思 ThreadTest test1 = new ThreadTest(10); ThreadTest test2 = new ThreadTest(20); ExecutorService executor = Executors.newFixedThreadPool(10); executor.execute(test1); //这个是你说的再次启用吗? executor.execute(test1); executor.shutdown(); 再次启用相当于从新开启一个线程,多个线程间是没有关系的,所以不存在“原来”的值 将代码稍微改下,如果还存在则会打印出“num exisit” if(n == null) { thLocal.set(num); } else { System.out.println("num exisit"); } tomcat 服务器线程池 就存在这样的情况,它是重启的空闲线程。 所以说与线程池的实现有点关系 |
|
返回顶楼 | |
发表时间:2010-10-22
感谢楼主分享!特意去读了下源代码,说下自己的理解:
每个线程都拥有一个自己的ThreadLocalMap对象,而这个对象的key是ThreadLocal类型的,这个key在每个线程中都是一样的,ThreadLocal只是作为一个索引。 之所以有线程局部变量这一说,是因为每个线程的ThreadLocalMap对象不同,那ThreadLocal类型的key当然可以指向不同对象了。 |
|
返回顶楼 | |