ThreadLocal使用场景以及和Synchronized的区别

ThreadLocal的优点:

线程安全的,思路通过分配空间到达换取时间,Synchronized是通过锁机制,让别的线程等待,是通过时间换取空间的思路;

ThreadLocal的缺点:

ThreadLocal是会造成内存溢出的

ThreadLocal使用场景以及和Synchronized的区别_第1张图片

ThreadLocal里面使用了一个存在弱引用的map,不过弱引用只是针对key。每个key都弱引用指向threadlocal。 当把threadlocal实例置为null以后,没有任何强引用指向threadlocal实例,所以threadlocal将会被gc回收。

但是,我们的value却不能回收,而这块value永远不会被访问到了,所以存在着内存泄露。因为存在一条从current thread连接过来的强引用。只有当前thread结束以后,current thread就不会存在栈中,强引用断开,Current Thread、Map value将全部被GC回收。

解决办法:调用threadlocal的remove方法

目前最典型的ThreadLocal的用法就是数据库连接

private static ThreadLocal connectionHolder = new ThreadLocal() {  
    public Connection initialValue() {  
        return DriverManager.getConnection(DB_URL);  
    }  
};  
  
public static Connection getConnection() {  
    return connectionHolder.get();  
}  

还有Session管理

关于session这里我提出的问题是:

我们既然可以使用httpsession,为什么还要多此一举考虑ThreadLocal来管理session?

我百度了一下,觉得应该是这两个原因:

1.HttpSession如果存放了大量的数据,会影响系统性能:

2.我们在controller层使用HttpSession比较方便,当我们想在service层或者dao层使用时,就比较麻烦了,需要从controller传值

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;  
}  

 

你可能感兴趣的:(java)