论坛首页 Java企业应用论坛

ThreadLocal-分析-总结

浏览 28250 次
精华帖 (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在他们中的重要性,但是那时还真的说不清楚,也就干脆没说。

回来觉得非常惭愧,所以仔细研究了一下,当然这个过程中参考很多网上的资料,如果你说部分有些相似,那我承认,但是抄那确实没有。
0 请登录后投票
   发表时间:2010-10-08  
存在线程池时,再次启用这个线程时,threadlocal原来的值还在吗?ps: 可能跟线程池的实现有关.
0 请登录后投票
   发表时间: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");
		}
  • 大小: 15.4 KB
  • 大小: 73.5 KB
0 请登录后投票
   发表时间:2010-10-10  
有问题请教楼主:
ThreadLocalSample这个demo不是 启动两个线程来访问共享资源public Integer num;  吗?

论坛里面也有说:
"ThreadLocal 不是用来解决共享对象的多线程访问问题的"

这怎么理解啊?


0 请登录后投票
   发表时间: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 不是用来解决共享对象的多线程访问问题的"
0 请登录后投票
   发表时间: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是每个线程吧?不知道这样理解对不对?望指教
0 请登录后投票
   发表时间:2010-10-10   最后修改:2010-10-10
错了,想了想,

ThreadLocalMap中key是每个ThreadLocal

ThreadLocal是在get方法时被每个线程自己的ThreadLocalMap加入的

ThreadLocal根据每个线程来决定get()方法返回的值



0 请登录后投票
   发表时间:2010-10-11  
这个帖子很详细
多学习下源码 就会很清楚了
0 请登录后投票
   发表时间: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 服务器线程池 就存在这样的情况,它是重启的空闲线程。 所以说与线程池的实现有点关系
0 请登录后投票
   发表时间:2010-10-22  
感谢楼主分享!特意去读了下源代码,说下自己的理解:
    每个线程都拥有一个自己的ThreadLocalMap对象,而这个对象的key是ThreadLocal类型的,这个key在每个线程中都是一样的,ThreadLocal只是作为一个索引。

    之所以有线程局部变量这一说,是因为每个线程的ThreadLocalMap对象不同,那ThreadLocal类型的key当然可以指向不同对象了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics