ThreadLocal一般用在哪些地方?有何用?

时间:2021-01-06 03:27:38
1、ThreadLocal跟共享有什么关系吗?

2、在Java Concurrency In Practice上看到一个例子:

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

public static Connection getConnection() {
return connectionHolder.get();
}

这个就是为每个线程都会开一个连接,而感觉如下也是一个线程开一个连接:

public static Connection getConnection() {
return DriverManager.getConnection(DB_URL);
}

是不是在有线程池的情况下以上两种方式才有区别?

3、除了上面上的Connection例子,还有在什么情况下会考虑用ThreadLocal?

谢谢

20 个解决方案

#1


线程不安全的类在多线程中使用,如 SimpleDateFormat;在一个线程中修改不影响其他线程的使用。

#2


对啊,在这里,2个类都是一个意思,为每个线程生成一个独立的连接。

#3


今天老师说了这个。。可以在同一个线程之中传递数据。要是你不用框架做javaee,你可能需要写处理事务的sql语句,你可以选择把一个Connection放在localthread里面,在service层取出来使用。

#4


楼上说的对 在事务管理上用的比较多

#5


所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

#6


1.ThreadLocal是线程局部 (thread-local) 变量,线程共享,我们写的程序一般是面像对象的,不是面向线程的,一个线程可能有N个对象,但他们工作时可能只需要共享一个资源,这个资源可以放在ThreadLocal里,当然,你愿意你以可以以参数形式在这个线上的每个对象之间传递( 这个相当麻烦)。
2.与有没有线程池无关。
3.有很多地方,比如在Hibernate中的Session(不是HTTP Session)

#7


该回复于2011-11-15 10:03:35被版主删除

#8


引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的


说得简单容易理解

#9


ThreadLocal是什么玩意可以多看一些开源的框架的源代码,里面大量使用了ThreadLocal。

#10


引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

ThreadLocal不是map没错,但是其实他里面有通过ThreadLocalMap来管理实现,ThreadLocalMap就是一张自定义的只为维护thread local values 的Hash Map, 这张map的key就是Thread.currentThread().

#11


该回复于2011-11-15 09:34:23被版主删除

#12


注意,ThreadLocal在那个线程里面put的值,那么一定要在同一个线程里面get,不然会获取出错的~~~
比如我们的web项目,用ThreadLocal保存session的值,结果异步任务无法从ThreadLocal里面获取正确的session。

#13


引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

之前大概看了下,其实它里面就是一个ThreadLocalMap,在get的时候先取到currentThread,看看map中有没有。
但是各位好像都没回答我的几个问题。

#14


java里面的变量的作用范围,有的是局部变量,有的是成员变量。局部变量永远不存在线程安全问题,成员变量是所有的线程所共享的,ThreadLocal的出现就弥补了这两种范围的一个不足,它比局部变量的范围要大,不仅仅是局限于一个方法块,但是又比成员变量的范围要小,因为它不会被多个线程共享,是线程独占的。

1、ThreadLocal跟共享有什么关系吗?

ThreadLocal是线程独占的。

2.
public static Connection getConnection() {
        return DriverManager.getConnection(DB_URL);
    }

这种方式多线程访问会有线程安全问题,ThreadLocal就不会。

3、除了上面上的Connection例子,还有在什么情况下会考虑用ThreadLocal?
。。。。

#15


引用 14 楼 goldenfish1919 的回复:
java里面的变量的作用范围,有的是局部变量,有的是成员变量。局部变量永远不存在线程安全问题,成员变量是所有的线程所共享的,ThreadLocal的出现就弥补了这两种范围的一个不足,它比局部变量的范围要大,不仅仅是局限于一个方法块,但是又比成员变量的范围要小,因为它不会被多个线程共享,是线程独占的。

1、ThreadLocal跟共享有什么关系吗?

ThreadLocal是线程独占的。
……

1、如何线程独占了?connectionHolder不是成员变量吗?
2、不是线程安全因为DriverManager.getConnection(DB_URL)不是线程安全的?

望大神说仔细些,确实没用过ThreadLocal,无法领会。

#16


说得很好!
引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

#17


引用 16 楼 licip 的回复:
说得很好!

引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的
看到一篇博客说过,还模拟实现了ThreadLocal,貌似不是我想要的,需要知道一种场景,没有ThreadLocal就不行~~~

#18


引用楼主 dreamhunter_lan 的回复:
1、ThreadLocal跟共享有什么关系吗?

2、在Java Concurrency In Practice上看到一个例子:

Java code


    private static ThreadLocal<Connection> connectionHolder
        = new ThreadLocal<Connection>() {
        pub……


与共享木有关系  ThreadLocal 是多线程中的免锁解决方案之一。 就是每个线程对于ThreadLocal 都有一个备份  ,这篇内存分配在堆上。


第二点  在两个线程同时执行getConnection()  的时候  会生成两个链接哦。

第三点 ThreadLocal  是多线程下的无锁定解决方案   主要用于保存 线程 的特征,比如你给线程重命名啦之类的 。  
核心是 每个线程中都有一个 ThreadLocal 的 副本  而 普通的则是共享的

#19


很到位!
引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

#20


ThreadLocal 主要还是在线程内部共享数据,很方便,让线程知道什么是自己的数据。

#1


线程不安全的类在多线程中使用,如 SimpleDateFormat;在一个线程中修改不影响其他线程的使用。

#2


对啊,在这里,2个类都是一个意思,为每个线程生成一个独立的连接。

#3


今天老师说了这个。。可以在同一个线程之中传递数据。要是你不用框架做javaee,你可能需要写处理事务的sql语句,你可以选择把一个Connection放在localthread里面,在service层取出来使用。

#4


楼上说的对 在事务管理上用的比较多

#5


所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

#6


1.ThreadLocal是线程局部 (thread-local) 变量,线程共享,我们写的程序一般是面像对象的,不是面向线程的,一个线程可能有N个对象,但他们工作时可能只需要共享一个资源,这个资源可以放在ThreadLocal里,当然,你愿意你以可以以参数形式在这个线上的每个对象之间传递( 这个相当麻烦)。
2.与有没有线程池无关。
3.有很多地方,比如在Hibernate中的Session(不是HTTP Session)

#7


该回复于2011-11-15 10:03:35被版主删除

#8


引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的


说得简单容易理解

#9


ThreadLocal是什么玩意可以多看一些开源的框架的源代码,里面大量使用了ThreadLocal。

#10


引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

ThreadLocal不是map没错,但是其实他里面有通过ThreadLocalMap来管理实现,ThreadLocalMap就是一张自定义的只为维护thread local values 的Hash Map, 这张map的key就是Thread.currentThread().

#11


该回复于2011-11-15 09:34:23被版主删除

#12


注意,ThreadLocal在那个线程里面put的值,那么一定要在同一个线程里面get,不然会获取出错的~~~
比如我们的web项目,用ThreadLocal保存session的值,结果异步任务无法从ThreadLocal里面获取正确的session。

#13


引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

之前大概看了下,其实它里面就是一个ThreadLocalMap,在get的时候先取到currentThread,看看map中有没有。
但是各位好像都没回答我的几个问题。

#14


java里面的变量的作用范围,有的是局部变量,有的是成员变量。局部变量永远不存在线程安全问题,成员变量是所有的线程所共享的,ThreadLocal的出现就弥补了这两种范围的一个不足,它比局部变量的范围要大,不仅仅是局限于一个方法块,但是又比成员变量的范围要小,因为它不会被多个线程共享,是线程独占的。

1、ThreadLocal跟共享有什么关系吗?

ThreadLocal是线程独占的。

2.
public static Connection getConnection() {
        return DriverManager.getConnection(DB_URL);
    }

这种方式多线程访问会有线程安全问题,ThreadLocal就不会。

3、除了上面上的Connection例子,还有在什么情况下会考虑用ThreadLocal?
。。。。

#15


引用 14 楼 goldenfish1919 的回复:
java里面的变量的作用范围,有的是局部变量,有的是成员变量。局部变量永远不存在线程安全问题,成员变量是所有的线程所共享的,ThreadLocal的出现就弥补了这两种范围的一个不足,它比局部变量的范围要大,不仅仅是局限于一个方法块,但是又比成员变量的范围要小,因为它不会被多个线程共享,是线程独占的。

1、ThreadLocal跟共享有什么关系吗?

ThreadLocal是线程独占的。
……

1、如何线程独占了?connectionHolder不是成员变量吗?
2、不是线程安全因为DriverManager.getConnection(DB_URL)不是线程安全的?

望大神说仔细些,确实没用过ThreadLocal,无法领会。

#16


说得很好!
引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

#17


引用 16 楼 licip 的回复:
说得很好!

引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的
看到一篇博客说过,还模拟实现了ThreadLocal,貌似不是我想要的,需要知道一种场景,没有ThreadLocal就不行~~~

#18


引用楼主 dreamhunter_lan 的回复:
1、ThreadLocal跟共享有什么关系吗?

2、在Java Concurrency In Practice上看到一个例子:

Java code


    private static ThreadLocal<Connection> connectionHolder
        = new ThreadLocal<Connection>() {
        pub……


与共享木有关系  ThreadLocal 是多线程中的免锁解决方案之一。 就是每个线程对于ThreadLocal 都有一个备份  ,这篇内存分配在堆上。


第二点  在两个线程同时执行getConnection()  的时候  会生成两个链接哦。

第三点 ThreadLocal  是多线程下的无锁定解决方案   主要用于保存 线程 的特征,比如你给线程重命名啦之类的 。  
核心是 每个线程中都有一个 ThreadLocal 的 副本  而 普通的则是共享的

#19


很到位!
引用 5 楼 ticmy 的回复:
所谓ThreadLocal,简单一点想,就是一个全局的Map,Map的key是线程对象,value是你要保存的对象

进入某个线程后,就可以从map中取得之前存储的相应线程关联的对象

当然,ThreadLocal并不是一个Map,但用Map来理解是没有问题的

#20


ThreadLocal 主要还是在线程内部共享数据,很方便,让线程知道什么是自己的数据。

#21