精华帖 (8) :: 良好帖 (15) :: 新手帖 (9) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-25
calmness 写道 LZ在ThreadLocal的使用上有误导,ThreadLocal并非是用于解决同步问题的,存在同步问题的问题它也解决不了,比如说一个统计类的系统,你能用ThreadLocal做到吗?难道为每个线程都copy一个计数器吗?那有什么用?ThreadLocal与synchronized 在使用上是没有可比性的,更没有谁替代谁的说法,帖子被评良好会导致不了解的人误解的。
你可能没有看完全文吧!!! 从来没有说过要用ThreadLocal代替synchronized |
|
返回顶楼 | |
发表时间:2007-05-25
jindw 写道 weiqingfei 写道 jindw 写道 weiqingfei 写道 其实两个本来就没有关系,我想楼主只是想说如何在多线程中活用ThreadLocal。
ThreadLocal的实现本来就比较简单,只是用线程来作为key来寻找本线程中所使用的一个实例,它解决的最主要的问题应该就是减少参数的传递。 说句没有意义的话,事实上。ThreadLocal实现中,作为key的不是线程,而是ThreadLocal本身。 从整体上来看好吧。 不要看到ThreadLocalMap的key是ThreadLocal,就认为寻找线程本地变量实例的key就是ThreadLocal了。 要知道每个线程都会持有一个ThreadLocalMap的实例,我说的key就是这个意思。 key只是找到目标的钥匙,不是只有map才有key。 你的话也有道理,但是,说到这个细节,我还是要说一下,ThreadLocal要比我们简单的想象复杂的多,不单是一个变量存储,它的数据方Thread里面,很明显,在线程销毁时的清理任务。 可以说ThreadLocal是个系统级的API,比我们想象的要复杂一点。 文中那个ThreadLocal的实现代码仅是一些猜想和stub! 为了更好的说明ThreadLocal |
|
返回顶楼 | |
发表时间:2007-05-25
BirdGu 写道 spiritfrog 写道 XMLDB 写道 LZ把概念搞错了,ThreadLocal就是ThreadLocal,和同步完全没有关系。
ThreadLocal解决的是同一个线程内的资源共享问题,而synchronized 解决的是多个线程间的资源共享问题,两个问题没有可比性。 lz的文章并没有去讨论ThreadLocal就是ThreadLocal有什么关系,只是在说如何保证多线程环境下对共享资源访问的数据安全。文章看完了,简单明了,很到位,是篇好文章。 麻烦你解释一下,ThreadLocal是怎么“保证多线程环境下对共享资源访问的数据安全”的?ThreadLocal使各个线程使用各自不同的数据,这种情况下哪来的“共享资源”? 就是告诉你多线程的时候什么时候用ThreadLocal,什么时候用而synchronized |
|
返回顶楼 | |
发表时间:2007-05-25
klyuan 写道 BirdGu 写道 spiritfrog 写道 XMLDB 写道 LZ把概念搞错了,ThreadLocal就是ThreadLocal,和同步完全没有关系。
ThreadLocal解决的是同一个线程内的资源共享问题,而synchronized 解决的是多个线程间的资源共享问题,两个问题没有可比性。 lz的文章并没有去讨论ThreadLocal就是ThreadLocal有什么关系,只是在说如何保证多线程环境下对共享资源访问的数据安全。文章看完了,简单明了,很到位,是篇好文章。 麻烦你解释一下,ThreadLocal是怎么“保证多线程环境下对共享资源访问的数据安全”的?ThreadLocal使各个线程使用各自不同的数据,这种情况下哪来的“共享资源”? 就是告诉你多线程的时候什么时候用ThreadLocal,什么时候用而synchronized 事实上,ThreadLocal就是为了不要数据共享,而是每个线程都有自己的数据,ThreadLocal和同步根本是不搭界的,而在楼主的文章里好像更容易把糊涂的人搞糊涂 再举个例子 楼主贴的ThreadLocal的猜想: public class ThreadLocal { private Map values = Collections.synchronizedMap(new HashMap()); public Object get() { Thread curThread = Thread.currentThread(); Object o = values.get(curThread); if (o == null && !values.containsKey(curThread)) { o = initialValue(); values.put(curThread, o); } return o; } public void set(Object newValue) { values.put(Thread.currentThread(), newValue); } public Object initialValue() { return null; } } 但是事实上不是这样的。 ThreadLocal应该是一个工具类,把数据通过ThreadLocal放到线程中去而已,每个线程都有自己的一个ThreadLocalMap(这个Map类是ThreadLocal的一个内部类)来存放这些变量,而楼主的代码是把这个变量存放在ThreadLocal中,在ThreadLocal中又对这个map进行同步。这个明显是不对的 我们看看jdk中的ThreadLocal就知道了: public Object get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) return map.get(this); // Maps are constructed lazily. if the map for this thread // doesn't exist, create it, with this ThreadLocal and its // initial value as its only entry. Object value = initialValue(); createMap(t, value); return value; } ThreadLocalMap getMap(Thread t) { return t.threadLocals; } void createMap(Thread t, Object firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } ps:楼主的文章误导人的字句确实不少(还有代码),如果改过来可投良好 |
|
返回顶楼 | |
发表时间:2007-05-25
ThreadLocal和synchronized除了都和多线程有关外,是没有太多的可比性,不应该放在一起说,这样确实会误导新手。
XMLDB的观点正解: ThreadLocal解决的是同一个线程内的资源共享问题,而synchronized 解决的是多个线程间的资源共享问题,两个问题没有可比性。 |
|
返回顶楼 | |
发表时间:2007-05-25
ahuaxuan 写道 但是事实上不是这样的。 ThreadLocal应该是一个工具类,把数据通过ThreadLocal放到线程中去而已,每个线程都有自己的一个ThreadLocalMap(这个Map类是ThreadLocal的一个内部类)来存放这些变量,而楼主的代码是把这个变量存放在ThreadLocal中,在ThreadLocal中又对这个map进行同步。这个明显是不对的 ps:楼主的文章误导人的字句确实不少(还有代码),如果改过来可投良好 应该是每个变量有一个ThreadLocalMap,然后每个ThreadLocalMap被所有线程共享吧? 我觉得楼主把这两个东西拿到一起来讨论是合理地,因为现实情况是:开发人员在很多没有必要用实例变量的场合却使用了一个实例变量,由此导致为了线程安全而使用synchronize,增加了复杂度,还有性能\死锁问题 而这种情况是可以用ThreadLocal来解决的 当然,需要在线程之间共享数据的时候,还是要用实例变量地 |
|
返回顶楼 | |
发表时间:2007-05-25
引用 Synchronized还是ThreadLocal? ThreadLocal以空间换取时间,提供了一种非常简便的多线程实现方式。因为多个线程并发访问无需进行等待,所以使用ThreadLocal会获得更大的性能。虽然使用ThreadLocal会带来更多的内存开销,但这点开销是微不足道的。因为保存在ThreadLocal中的对象,通常都是比较小的对象。另外使用ThreadLocal不能使用原子类型,只能使用Object类型。ThreadLocal的使用比synchronized要简单得多。 其他先不说,我想通过这段话就可以看出你把Synchronized和ThreadLocal放在可比可替换的情况下了吧,至少这里就已经做出了误导。 |
|
返回顶楼 | |
发表时间:2007-05-25
to daquan: ahuaxuan说的没错。
|
|
返回顶楼 | |
发表时间:2007-05-25
ahuaxuan 写道 我们看看jdk中的ThreadLocal就知道了: public Object get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) return map.get(this); // Maps are constructed lazily. if the map for this thread // doesn't exist, create it, with this ThreadLocal and its // initial value as its only entry. Object value = initialValue(); createMap(t, value); return value; } ThreadLocalMap getMap(Thread t) { return t.threadLocals; } void createMap(Thread t, Object firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } 哦,是我搞错了.又仔细看了一下这段代码 |
|
返回顶楼 | |
发表时间:2007-05-25
是啊,楼主和好多人一样对ThreadLocal的理解有较大的偏差,可以看看这一篇文章:http://www.iteye.com/topic/71554,里面介绍的很清楚,相信对大家有帮助。
|
|
返回顶楼 | |