之前用到过ThreadLocal ,没仔细看,最近又用到,使用过程中感到理解有偏差,所以想搞清楚。
首先说一下web容器的多线程。当Web容器收到一个Http请求时,Web容器中的一个主调度线程会从事先定义好的线程池中分配一个当前工作线程,将请求分配给当前的工作线程,由该线程来执行对应的Servlet对象中的service方法。如果这个工作线程正在执行的时候,Web容器收到另外一个请求,主调度线程会同样从线程池中选择另一个工作线程来服务新的请求。Web容器本身并不关心这个新的请求是否访问的是同一个Servlet实例。因此,我们可以得出一个结论:对于同一个Servlet对象的多个请求,Servlet的service方法将在一个多线程的环境中并发执行。
一. ThreadLocal 是一个java类。他提供了多线程环境下线程安全的数据访问。
二. 先从servlet和struts1和struts2谈起。Servlet和struts1一样,是线程不安全的,也就是说,servlet和struts1的一个类的对象在服务器端只有一份实例,这意味着使用servlet和struts1时,不允许在类中定义成员变量(静态变量不予考虑),这样会引起并发访问时的数据安全问题。而struts2解决了线程安全问题,他的action在服务器端随着request请求生成多份实例。
三. 之前理解的Threadlocal是这样的:
Threadlocal类似一个Map,它的key是当前线程id,value是绑定值。
(这样理解的漏洞:1如果一个线程销毁,那它的绑定数据会残留在Threadlocal中,如果由jvm来处理,是比较耗时的。2Threadlocal像一个全局变量,存放了所有线程的相关变量,那么线程之间的数据无法隔离)
看过源码和分析后,理解如下:
1. ThreadLocal下有一个静态类ThreadLocalMap的定义,这个Map可以理解为普通Map,它的key是ThreadLocal对象;
2. 每个Thread对象有一个静态类ThreadLocalMap的实例属性,也就是说每个线程维护它自己的变量容器,有多少个ThreadLocal定义,该容器就可以容纳多少个key-value键值对;
3. ThreadLocal类支持泛型,可以理解为一个ThreadLocal对象只针对一种实体类做参数绑定;
4. 在一个线程请求处理过程中,线程自己的Map是放在那里的,同时,ThreadLcoal一般被声明为static的。
因此,可以随时以ThreadLocal的静态实例引用(不变化)为key将某待绑定变量值set进去;
因此,随时可以通过ThreadLocal的静态实例引用(不变化)为key去查找当前线程下绑定的该变量值;
附ThreadLocal部分源码:
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
四. ThreadLocal+Thread实现的效果
纵向隔离 —— 线程(Thread)与线程(Thread)之间的数据访问隔离。这一点由线程(Thread)的数据结构保证。因为每个线程(Thread)在进行对象访问时,访问的都是各自线程自己的ThreadLocalMap。
横向隔离 —— 同一个线程中,不同的ThreadLocal实例操作的对象之间的相互隔离。这一点由ThreadLocalMap在存储时,采用当前ThreadLocal的实例作为key来保证。
跨层存在—— ThreadLocal模式的核心在于实现一个共享环境(类的内部封装了ThreadLocal的静态实例)。所以,在操作ThreadLocal时,这一共享环境会跨越多个开发层次(比如view层、service层、dao层)而随处存在。
由于图片无法正常显示,请下载附件!
分享到:
相关推荐
### ThreadLocal基本使用 创建ThreadLocal实例时,通常会定义一个泛型参数,代表该线程局部变量的类型。例如: ```java ThreadLocal<String> threadLocal = new ThreadLocal(); ``` ### 设置和获取值 在...
ThreadLocal使用案例_动力节点Java学院整理 ThreadLocal是Java中的一种多线程机制,主要用于解决多线程之间的共享变量问题。在Java中,每个线程都有自己的ThreadLocal变量副本,通过ThreadLocal可以实现线程安全的...
以下是一个简单的ThreadLocal使用示例,展示了如何为每个线程创建一个独立的`SimpleDateFormat`实例: ```java package com.javapapers; import java.text.SimpleDateFormat; import java.util.Date; public ...
Java ThreadLocal使用案例详解 Java ThreadLocal是Java语言中的一种机制,用于为每个线程提供一个独立的变量副本,以解决多线程环境下共享变量的线程安全问题。在本文中,我们将详细介绍Java ThreadLocal的使用案例...
4. **减少锁的使用**: 当多个线程需要共享同一资源,但每个线程只需要读取自己相关的数据时,`ThreadLocal`可以避免锁的使用,提升效率。 **注意事项** - 使用`ThreadLocal`后,应确保及时清理不再使用的变量,...
【Android中的ThreadLocal使用示例】 ThreadLocal是Java(因此也适用于Android)中的一种特殊变量类型,它允许每个线程拥有变量的独立副本。在多线程环境下,ThreadLocal可以帮助我们实现线程间的隔离,避免数据...
为了解决这个问题,通常会使用数据库连接池技术,配合ThreadLocal使用,确保每次线程中获得的数据库连接都是一致的。这样,同一线程内的多个数据库操作可以共享同一个连接,从而保证了事务的一致性,并且提高了...
下面是一个简单的ThreadLocal使用示例: ```java public class MainActivity extends AppCompatActivity { private ThreadLocal<Person> mThreadLocal = new ThreadLocal(); private Person mPerson = new Person...
下面我们将深入探讨`ThreadLocal`的工作原理、使用场景以及常见误区。 `ThreadLocal`类的主要方法有以下几个: 1. `void set(T value)`:设置当前线程的线程局部变量的值。 2. `T get()`:返回当前线程的线程局部...
8. **缺点与注意事项**:ThreadLocal使用不当可能导致内存泄漏,尤其是在Web应用中,需要确保在Web请求结束时清理ThreadLocal。此外,过多的ThreadLocal变量也可能增加内存消耗。 总结起来,"Hibernage_Session_...
下面是一个简单的ThreadLocal使用示例: ```java public class ThreadLocalSample { public static void main(String[] args) { ThreadTest test1 = new ThreadTest(10); ThreadTest test2 = new ThreadTest(20)...
本篇文章将聚焦于Spring事务处理中ThreadLocal的使用,以及如何通过源码理解和应用这个工具。 首先,了解Spring事务管理的基本概念。在多线程环境中,事务管理是至关重要的,它负责确保一组数据库操作要么全部成功...
以下是一个简单的ThreadLocal使用示例,创建了一个`SequenceNumber`类,其中使用ThreadLocal存储每个线程独立的序列号。每个线程都有自己的序列号计数器,互不干扰: ```java public class SequenceNumber { ...
深入理解ThreadLocal工作原理及使用示例 ThreadLocal是Java提供的一种解决多线程程序并发问题的工具类,自JDK1.2版本以来提供了java.lang.ThreadLocal类。ThreadLocal的主要作用是为每个使用该变量的线程提供独立的...
ThreadLocal内部使用了一个ThreadLocalMap,它是一个基于ThreadLocal实例作为键,值为用户存储对象的弱引用表。每个线程都有一个这样的ThreadLocalMap,保证了线程间数据的隔离。 6. **工具支持** 在实际开发中,...
本文将深入探讨ThreadLocal的使用以及Spring框架中的事务管理,这两个主题都是Java开发人员必须掌握的关键技能。 首先,让我们了解ThreadLocal。ThreadLocal是Java提供的一种线程绑定变量的工具类,它允许我们在一...
理解ThreadLocal的工作原理和使用方法对于编写高效、安全的多线程程序至关重要。 ### ThreadLocal简介 ThreadLocal并非一个线程对象,而是一个线程局部变量的容器。每个线程都有自己的ThreadLocal实例,它们各自...