精华帖 (8) :: 良好帖 (15) :: 新手帖 (9) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-30
lujh99 写道 这种情况确实没有必要存在,但是如果非要制造出这种情况也是可能的。
比如Spring应用中的service类是单例的,action类是多例的,service被注入到action中。如果service类中有一个成员对象A(纯粹举例子,实际不会这么用),action类中有个static的ThreadLocal。 那么有多个request的话就有多个线程在运行,在线程中可以将对象A通过ThreadLocal的set方法放到线程中,通过ThreadLocal的get方法取出来,难道你说放到多个线程中的对象A不是同一个对象吗?取出来的不是同一个对象吗?实际放进去的就是一个引用而已。怎么能说“保证了任何一个线程都拥有属于自己的实例”呢? 以上例子仅仅为了说法这个说法是不对的,实际不会这样使用。跟action类是不是多例也没有太大关系。 另:小伙怎么跑到上海去了 在你说的这种情形下确实是这样的 但是也确实不会这样用的,呵呵 ps:来上海已经快两个月了:) |
|
返回顶楼 | |
发表时间:2007-05-30
lujh99 写道 eway 写道 ThreadLocal本身的作用是保证任何一个线程都拥有属于自己的实例,...
这个正是楼主错误的观点, 如果一个类中定义了一个static的ThreadLocal,一个共享对象可以通过该ThreadLocal的set设置到多个线程的ThreadLocalMap中,但是这多个线程的ThreadLocalMap中存着的仅仅是该对象的引用,指向那个共享对象,而不是什么副本,通过ThreadLocal的get方法取到的是就是那个共享对象本身,共享访问安全问题还是要靠其他方法来解决。 用过HibernateUtil吧?看看怎么写的。。。你明白不为什么要用这个类?不是为了保证每个线程都有一个属于自己的独立的session,同时这个session又是一个线程内部所共享的么? public static final ThreadLocal sessionLocal = new ThreadLocal(); public static Session currentSession() throws HibernateException { Session session = (Session) sessionLocal.get(); if (session == null) { session = sessionFactory.openSession(); sessionLocal.set(session); } return session; } 再看看ThreadLocal的set方法干啥! map.put(Thread.currentThread,object); 如果你读懂了,应该可以明白每个不同的线程都会在ThreadLocal中put进去不同的新session对象,而不是你理解的不同引用。 你不觉得自己太牵强了么?拿一个不自己都说在实际中不会用的例子过来证明什么,能证明什么呢? 你不会不知道ThreadLocal在Hibernate中的上述实际应用吧?这样的用法才是ThreadLocal的真正应用的场景,也就是我之前说过的,这个类来保证每个线程一个实例,并且每个线程都只有一个该线程内部共享的实例。 想告诉你lujh99,你对ThreadLocal的理解才是彻头彻尾的错误,比楼主理解的偏差相差的更远! |
|
返回顶楼 | |
发表时间:2007-05-30
eway 写道 再看看ThreadLocal的set方法干啥! map.put(Thread.currentThread,object); 拜托,那是楼主自己瞎写的,你还真信了,即使真是这样,放进去的也是一个引用啊。 不跟你争了,你还是去看看java的源码吧。 |
|
返回顶楼 | |
发表时间:2007-05-30
lujh99 写道 eway 写道 再看看ThreadLocal的set方法干啥! map.put(Thread.currentThread,object); 拜托,那是楼主自己瞎写的,你还真信了,即使真是这样,放进去的也是一个引用啊。 不跟你争了,你还是去看看java的源码吧。 你可真逗,拿java源码给你看。。。 ![]() public void set(Object value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } |
|
返回顶楼 | |
发表时间:2007-05-30
lujh99 写道 真是无语了...
应该说语塞,和无语有区别滴。。。倒想听听你还有什么"高论"? |
|
返回顶楼 | |
发表时间:2007-05-30
我也不想说你什么了,只能说你太粗心了,再仔细看看吧
|
|
返回顶楼 | |
发表时间:2007-05-30
那年夏天 写道 终于找到详细的ThreadLocal介绍了
阳光晒晒 写道 汗。。。如果有其它的建议先看看别的。。
这翩文章很有争议性。 仔细看过Hibernate中对Session 在不同的线程里保存的例子之后,还是感觉楼主的解释是很清晰的 |
|
返回顶楼 | |
发表时间:2007-05-30
ThreadLocal确实没办法保证一线程一个实例。很可能这个实例本来就是多线程共享的。
假如本来就被多个线程共享了,那就没办法保证安全了! 就像struts action的一个属性。放进去还是非线程安全。 这样使用类似set(new Object());不让别的线程拿到这个对象的引用,这样才能线程安全。 不过和synchronized这种虚拟机直接强制同步是本质上的不同。 |
|
返回顶楼 | |
发表时间:2007-05-30
eway 写道 lujh99 写道 真是无语了...
应该说语塞,和无语有区别滴。。。倒想听听你还有什么"高论"? 想听听你现在的看法是怎样的? |
|
返回顶楼 | |
发表时间:2007-05-30
例子不好,说明不了什么问题,
第一个例子和第二个例子边都挨不上; 第一个例子,两个Thread,分享一个Student实例 第二个呢?ThreadLocal类不是 new ThreadLocal(),然后set一下,就多线程共享的。 |
|
返回顶楼 | |