该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-16
public class SampleClass { public static final ThreadLocal session = new ThreadLocal(); ... } 以上这段代码,一个普通的类,里面一个static成员,成员类型为“ThreadLocal”,并且是final的。 通常我们很熟悉,类里面“static final”的东东都是JVM 唯一的,可以用来放一些常量。 但是,现在,按照“ThreadLocal”的定义,每一个执行到此语句的thread都会得到自己的一个“session”实例。这也是我们用来解决 Hibernate open session in view 的办法。 那么,请教了,在这种既“static”,又“ThreadLocal”的情况下,整个 JVM 里面的“session”实例,到底是单个还是多个呢? 如果是多个,是否可以说,Java类的“static”成员将不一定是JVM 唯一的,而是取决于此“static”成员的类型? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-04-16
对一个新实例把旧实例替掉。。。。
|
|
返回顶楼 | |
发表时间:2007-04-16
至少这个数是针对每个线程的
|
|
返回顶楼 | |
发表时间:2007-04-16
ThreadLocal 是个容器,可以简单理解成hashmap,
key就是线程,值就是当前线程能够得到的东西. 有时间在这里乱猜测,还不如认真仔细读下 ThreadLocal 的源代码!!! |
|
返回顶楼 | |
发表时间:2007-04-16
再写几个单元测试验证一下想法。
|
|
返回顶楼 | |
发表时间:2007-04-16
其实,我虽然有疑问,也是倾向于认为“static”的“ThreadLocal”成员在 JVM 里面是多个的。
Java源码没看过,但“ThreadLocal”的参考实现看过,基本上就是 JVM 里面的一个Map,key 就是当前的 thread,value 就是“ThreadLocal”变量。照这样看来,“ThreadLocal”成员,无论“static”与否,在 JVM 里面总是多个的。 我的疑问,主要在于Java编译器以及JVM在这种既“static”又“ThreadLocal”的情况下的处理办法。我自己一直在想办法,多学些扎实的基础。基础扎实些,总是好的:) |
|
返回顶楼 | |
发表时间:2007-04-17
这个不难的,看看源代码就明白了。static的ThreadLocal对象在同一个JVM下同一个ClassLoader中只有一个,不然java语言就乱了。
这个ThreadLocal的内部成员只有一个,int threadLocalHashCode,还是个final。这个ThreadLocal,只是提供了对thread local storage的操作,而不含有数据。 那么thread local的数据在哪里呢?在Thread对象里。 去看看Thread的源代码,第157行, ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocal类里面有个static类,ThreadLocalMap,这个类内部是用array实现的。 Thread对象是由操作系统创建的,初始threadLocals为null。 第一次使用ThreadLocal的get()时,如果threadLocals为null,创建个新的ThreadLocal.ThreadLocalMap对象。 下面是ThreadLocal里相对的代码,为了增强可读性我编辑了一下。 public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = t.threadLocals; if (map != null) return (T)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. T value = initialValue(); t.threadLocals = new ThreadLocalMap(this, firstValue); return value; } ThreadLocal实际上是当map key使,这个key是个int,hash混了一把后生成。 |
|
返回顶楼 | |
发表时间:2007-04-17
非典型程序员 写道 public class SampleClass { public static final ThreadLocal session = new ThreadLocal(); ... } 以上这段代码,一个普通的类,里面一个static成员,成员类型为“ThreadLocal”,并且是final的。 通常我们很熟悉,类里面“static final”的东东都是JVM 唯一的,可以用来放一些常量。 但是,现在,按照“ThreadLocal”的定义,每一个执行到此语句的thread都会得到自己的一个“session”实例。这也是我们用来解决 Hibernate open session in view 的办法。 那么,请教了,在这种既“static”,又“ThreadLocal”的情况下,整个 JVM 里面的“session”实例,到底是单个还是多个呢? 如果是多个,是否可以说,Java类的“static”成员将不一定是JVM 唯一的,而是取决于此“static”成员的类型? “session”实例是单个,里面只有一个数据,private final int threadLocalHashCode. 所有的ThreadLocal的对象,这个threadLocalHashCode值都不一样。这个hash code是用来当map key用的。实现方法也不难。 private final int threadLocalHashCode = nextHashCode(); private static int nextHashCode = 0; private static final int HASH_INCREMENT = 0x61c88647; private static synchronized int nextHashCode() { int h = nextHashCode; nextHashCode = h + HASH_INCREMENT; return h; } 问题解完,星星拿来, |
|
返回顶楼 | |
发表时间:2007-04-17
初级会员没有星给你个4星
|
|
返回顶楼 | |
发表时间:2007-04-17
非常感谢 bigpanda 的详细回答!有些细节还不是很懂,比如说原来以为 Map 的 key 应该是当前 Thread,但现在看来应该是 ThreadLocal??
无论如何,我马上写了一个测试,发现 bigpanda 是正确的! public class ThreadLocalTest { private static final ThreadLocal testThreadLocal = new ThreadLocal(); private static class TestThread implements Runnable { private ThreadLocal threadLocal; public TestThread(ThreadLocal threadLocal) { this.threadLocal = threadLocal; this.threadLocal.set(new Object()); } public void run() { System.out.println("=========="); System.out.println("ThreadLocal object passed in: " + System.identityHashCode(threadLocal)); System.out.println("ThreadLocal object content: " + System.identityHashCode(threadLocal.get())); System.out.println("=========="); } } public static void main(String[] args) { for (int i = 0; i < 6; i ++) { new Thread(new TestThread(testThreadLocal)).run(); } } } 结果,只有一个 threadLocal 实例,但 threadLocal.get() 的结果为多个,且对应多个 Thread 的! 嘻嘻,可惜还是新手,不能送星星~~ |
|
返回顶楼 | |