先给出两个链接:
第一篇:http://www.iteye.com/topic/103804
第二篇:http://blog.csdn.net/qjyong/article/details/2158097
我觉的这两篇文章都讲的不错,但是我觉的这两篇文章好像有一个地方观点是不一样的,第一篇文章在总结处说道:
总之,ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。
而第二篇文章说道:
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
大家是怎么认为的呢?

解决方案 »

  1.   

    不矛盾啊,ThreadLocal是通过线程私有对象避免同步,而不是解决同步。各个线程得到的是资源的拷贝,因而不需要互斥访问。
      

  2.   

    ThreadLocal的存在就是解决同步的问题的吧,,,Thread是通过锁机制解决同步问题,采用的是用时间换空间,而ThreadLocal采用的是以空间换时间!!为什么说ThreadLocal不是解决同步呢??
      

  3.   

    我感觉ThreadLocal不单单是空间换时间,能用ThreadLocal还有个条件就是:各个线程内部的版本不能相互依赖。你比如说统计在线人数这个功能,每个新登录的线程要在原有基础上增1,这种情况ThreadLocal就用不上。我感觉“共享”和“同步”是两个问题,你完全可以只共享,不同步,当然同步的前提是你能看到它。所以我感觉硬要说ThreadLocal解决了共享数据问题,那也只是共享了初值,一旦数据被限制在线程内部就完全不涉及共享的问题了。由于这种线程封闭的做法本质上是复制数据,所以根本和同步没关系,同步操作的是同一份数据。个人看法哈,楼下楼上请指教。
      

  4.   

    同意你的看法,但是还有个疑问,ThreadLocal就是把变量变为线程内部的私有变量,那么跟直接在线程使用局部变量不同吗?每个线程的局部变量又不为相互影响。所以我觉的第一篇文章作者说:
    主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。。这句话很有道理
      

  5.   

    1、ThreadLocal主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。
      这个直接通过threadLocal的get()很好理解。
    2、ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
      threadLocal为相同变量的访问提供了“同步”:说的是你通过对threadLocal是否存在当前变量进而决定是新建变量还是返回threadLocal中存在的变量,这个同步是threadlocal和你的判断共同实现的,不是threadLocal单独能完成的。以上拙见,恳请赐教
      

  6.   


    我感觉跟直接在线程使用局部变量有不同。使用线程内部的变量的话,数据完全是来自本线程,使用ThreadLocal的话,那个“初始数据”是另外一个线程给你的不知我说清楚没。。
      

  7.   


    刚去看了下源码ThreadLocal里面有个静态嵌套类,叫ThreadLocalMap。这里面就存了属于某个线程的变量。然后这个
    ThreadLocalMap实例放在代表那个线程的Thread对象中。这是ThreadLocal的set方法:
    public void set(T value) {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
        }
    //又用到了getMap方法ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
        }
    //这个t是当前线程对象,threadLocals就是最开始提到的那个存放数据的Map//Thread中就对应这个成员变量/* ThreadLocal values pertaining to this thread. This map is maintained
         * by the ThreadLocal class. */
        ThreadLocal.ThreadLocalMap threadLocals = null;//ThreadLocalMap的set方法有点复杂,它在实现一个简单的类似HashMap的东西,ThreadLocalMap中的key用的是
    //ThreadLocal中的threadLocalHashCode字段。private void set(ThreadLocal key, Object value) {            // We don't use a fast path as with get() because it is at
                // least as common to use set() to create new entries as
                // it is to replace existing ones, in which case, a fast
                // path would fail more often than not.            Entry[] tab = table;
                int len = tab.length;
                int i = key.threadLocalHashCode & (len-1);            for (Entry e = tab[i];
                     e != null;
                     e = tab[i = nextIndex(i, len)]) {
                    ThreadLocal k = e.get();                if (k == key) {
                        e.value = value;
                        return;
                    }                if (k == null) {
                        replaceStaleEntry(key, value, i);
                        return;
                    }
                }            tab[i] = new Entry(key, value);
                int sz = ++size;
                if (!cleanSomeSlots(i, sz) && sz >= threshold)
                    rehash();
            }//这是threadLocalHashCode字段:private final int threadLocalHashCode = nextHashCode();    /**
         * The next hash code to be given out. Updated atomically. Starts at
         * zero.
         */
        private static AtomicInteger nextHashCode =
            new AtomicInteger();总之他是想唯一标示ThreadLocal对象。再来瞅瞅ThreadLocal的get方法public T get() {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null) {
                ThreadLocalMap.Entry e = map.getEntry(this);
                if (e != null)
                    return (T)e.value;
            }
            return setInitialValue();
        }
    //getMap(t)得到的是当前线程对象中的ThreadLocalMap对象,
    然后按照当前对象的hashcode就找到了Entry,Entry里面就是你原来放进去的对象。
    ThreadLocal等于是吧线程专属数据放Thread对象里面了,这样线程之间就好像有个各自的名字空间,每个线程有各自一套变量。就不用处理并发了。不知代码看的对不对 lz请继续拍砖。。