看完lujh99的正确理解ThreadLocal一文,使我对ThreadLocal有了一个全面的了解,具体的原理我就不再复述,下面用个小例子来说明具体项目中的使用,先上类图:
public class User {
private String id;
private String name;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public class BizServer {
UserManager userManager;
public void getUserInfo(){
User user = userManager.getUser();
System.out.println("user : " + user);
}
}
public class UserManager {
private static final ThreadLocal<User> threadLocal = new ThreadLocal<User>();
public void setUser(User user){
threadLocal.set(user);
}
public User getUser(){
return threadLocal.get();
}
}
很简单的三个类,下面是简单的类图:
再来看看调用过程:
从上面来看,用户线程1来调用业务类BizServer的getUserInfo()方法来获取信息,而BizServer是委托UserManager来获取用户信息的,UserManager则是调用threadLocal,而threadLocal最终是在threadLocalMap中来获取信息的,各位注意了,这个threadLocalMap是每个线程都有的属性,因此,绕了一圈,Thread1这个线程对象是从自己的threadLocalMap里去拿数据,有点囧吧。
然后我们反过来想,那我们直接从thread对象中获取不就得了,没必要绕这么大一圈吧?呵呵,我个人第一反应也是这样的,然后看了看源代码,就明白为什么要这么做了,理由如下:
1.threadLocalMap属性是default的,这种属性只有相同包下的类才能访问,这也是为什么ThreadLocal这个类可以访问的原因
2.如果thread类把threadLocalMap设为公有的,那么谁来保证里面键值的唯一性?要知道,这个是Map,你可以存很多数据的,只要key不同。因此ThreadLocal类来做key,用以保证key的唯一性(具体做法lujh99已经说过了,我就不再重复)
我们再反过来UserManager 这个类,我们把threadLocal 这个属性设为static final的,final没必要多解释,防止修改嘛,这个可以理解,不然没办法做key了,再看看static,这个是用来保证所有线程进来都使用同一个ThreadLocal对象来做key,
这样key就唯一了但由于value是存在各个线程自己的threadLocalMap里的,因此也不会出再数据覆盖.现在我们想想,这个static就是为了保证ThreadLocal对象唯一嘛,实际上,我们把UserManager设为单例的,这样ThreadLocal也闵唯一了,因此,这里只要UserManager为单例的,ThreadLocal不是static也是可以的,但为了保险起见,还是设为static为好,除非你可以保证UserManager一定是单例的.
以上就是我对ThreadLocal的总结,由于本人水平有限,失误之处欢迎拍砖。
- 大小: 7.7 KB
- 大小: 6.8 KB
分享到:
相关推荐
- 使用完毕后,应调用`remove()`方法清除ThreadLocal变量,防止内存泄漏。 - 尽量避免将ThreadLocal用作长期持有的全局变量,尤其是在静态方法或静态变量中使用。 - 避免过度依赖ThreadLocal,因为它可能导致设计上...
在Java中,ThreadLocal的工作原理是为每个线程创建一个单独的存储空间,每个线程可以独立地读写这个变量,而不会影响其他线程。当我们创建一个新的ThreadLocal实例时,它并不会立即分配内存,而是等到线程第一次调用...
因此,推荐在不再使用ThreadLocal时显式调用`remove()`方法。 ```java threadLocal.remove(); ``` ### 示例:线程安全的计数器 假设我们需要一个线程安全的计数器,可以使用ThreadLocal实现: ```java public ...
首先,ThreadLocal原理是基于每个线程创建一个私有的数据存储结构(ThreadLocalMap),使得线程可以拥有自己独立的数据副本,而不会与其他线程共享。这意味着,即使多个线程访问相同的变量,它们也各自拥有这个变量...
下面将对 ThreadLocal 的原理、实现机制、使用方法等进行深入分析。 什么是 ThreadLocal? ThreadLocal 翻译过来就是本地线程,但是直接这么翻译很难理解 ThreadLocal 的作用。如果换一种说法,可以称为线程本地...
ThreadLocal是Java中用于线程局部变量的一个工具类,它的工作原理主要体现在如何在不同的线程之间隔离变量的副本,确保每个线程拥有自己的独立数据。这个设计模式在多线程编程中尤其有用,因为它避免了传统的同步...
- 当你对ThreadLocal进行`set()`操作时,实际上是将值放入了当前线程的ThreadLocalMap中,键是ThreadLocal对象本身,值是你设置的对象。 - 当你调用`get()`时,它会查找当前线程的ThreadLocalMap,找到对应的键(即...
ThreadLocal原理分析图,visio软件打开
### 正确理解ThreadLocal:深入解析其工作原理与应用场景 #### 一、ThreadLocal的基本概念 `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每...
当我们调用`set`方法时,会将键值对(键是`ThreadLocal`实例,值是我们设置的对象)放入当前线程的`ThreadLocalMap`中。`get`方法则根据当前线程查找对应的键值对。 使用场景: 1. **线程安全的配置**:每个线程...
理解ThreadLocal的工作原理和使用方法对于编写高效、安全的多线程程序至关重要。 ### ThreadLocal简介 ThreadLocal并非一个线程对象,而是一个线程局部变量的容器。每个线程都有自己的ThreadLocal实例,它们各自...
因此,正确使用`ThreadLocal`的一个关键点是在线程结束或不再使用ThreadLocal时,及时调用`remove()`。 工具应用: 在实际开发中,ThreadLocal常用于缓存线程相关的数据,如数据库连接、事务管理、请求上下文等。...
ThreadLocal的工作原理可以通过图片来阐述: 首先,当我们创建一个ThreadLocal对象时,ThreadLocal将为每个线程提供一个独立的变量副本。 当我们调用get方法时,ThreadLocal将返回当前线程的变量副本。 当我们...
学习ThreadLocal,了解其中的原理,以及学习其中的优点!避免坑点!!
- **请求上下文传播**:在Web开发中,可以将HttpServletRequest对象放入ThreadLocal,以便在同一个请求处理过程中方便地访问请求信息。 - **缓存**:在某些场景下,可以为每个线程提供一个本地缓存,避免了多线程...
at 中专门为每一个 web 应用...理解 `ThreadLocal` 的工作原理以及它如何与类加载器交互,是避免此类问题的关键。在实际开发中,应当养成良好的编程习惯,如使用后及时清理 `ThreadLocal` 变量,以防止内存资源的浪费。
ThreadLocal是Java编程语言中的一个强大工具,它主要用于在多线程环境中为每个线程提供独立的变量副本。这个机制确保了线程之间的数据隔离,避免了共享状态带来的并发问题,提高了程序的安全性和效率。ThreadLocal是...