import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadLocalTest {
public static void main(String[] args) {
MyThreadPoolExecutor pool = new MyThreadPoolExecutor(2, 2, 10,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000));
int i = 0;
while (true) {
final int loop = i++;
// 进行set的Runnable
pool.execute(new Runnable() {
@Override
public void run() {
MyThreadLocal.currentAgentId.set(1);
System.out.println(loop + "=1==" + Thread.currentThread()
+ "seted currentAgentId:"
+ MyThreadLocal.currentAgentId.get());
}
});
pool.execute(new Runnable() {
@Override
public void run() {
System.err.println(loop + "=2==" + Thread.currentThread()
+ "seted currentAgentId:"
+ MyThreadLocal.currentAgentId.get());
}
});
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(loop + "=3==" + Thread.currentThread()
+ "seted currentAgentId:"
+ MyThreadLocal.currentAgentId.get());
}
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("================");
}
// pool.shutdown();
}
}
class MyThreadPoolExecutor extends ThreadPoolExecutor {
public MyThreadPoolExecutor(int i, int j, int k, TimeUnit seconds,
ArrayBlockingQueue<Runnable> arrayBlockingQueue) {
super(i, j, k, seconds, arrayBlockingQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
//任务执行回调可以作为重置操作
MyThreadLocal.currentAgentId.set(888);
}
protected void afterExecute(Runnable r, Throwable t) {
//任务执行回调可以作为重置操作
MyThreadLocal.currentAgentId.set(null);
}
}
abstract class MyThreadLocal {
public static ThreadLocal<Integer> currentAgentId = new ThreadLocal<Integer>();
}
分享到:
相关推荐
然而,在实际生产中,线程一般不可能孤立的独立去运行,而是交给线程池去调度处理。这时,ThreadLocal 的局限性就暴露出来了,即它不能解决跨线程池之间的数据传递问题。 为了解决这个问题,...
- 尽量避免将ThreadLocal用作长期持有的全局变量,尤其是在静态方法或静态变量中使用。 - 避免过度依赖ThreadLocal,因为它可能导致设计上的复杂性和难以维护的问题。 综上所述,ThreadLocal是Java多线程编程中的一...
1. 存储当前会话用户信息:例如,可以在一个线程中使用ThreadLocal保存用户的登录状态,确保每个线程只处理一个用户的信息。 2. 存放上下文变量:如WebWork的ActionContext,它可以保存请求处理过程中的各种上下文...
通过ThreadLocal,可以保证这些信息在Action的不同调用中保持一致,即在同一个请求的不同阶段中,即使使用不同的线程去处理,它们依然能访问到相同的上下文信息。 黄老邪,作为京东的资深架构师,拥有近20年的行业...
4. **注意线程池中的ThreadLocal**:线程池中的线程可能会被重用,若不清理ThreadLocal,可能导致后续任务访问到错误的变量副本。 通过理解ThreadLocal的原理和最佳实践,我们可以更有效地利用它来解决多线程环境下...
在 `LeakingServlet` 的 `doGet` 方法中,如果 `ThreadLocal` 没有设置值,那么会创建一个新的 `MyCounter` 并设置到 `ThreadLocal` 中。关键在于,一旦 `MyCounter` 被设置到 `ThreadLocal`,那么它将与当前线程...
1. 初始化:每个工作线程在启动时,可能会初始化一些线程局部变量,如ThreadLocal,以便在执行任务时保持独立的数据环境。 2. 执行任务:PooledThread会有一个run方法,该方法从工作队列中取出任务并执行。执行完毕...
然而,在使用 ThreadLocal 时,可能会出现内存泄漏和数据丢失问题。本文将对 ThreadLocal 中内存泄漏和数据丢失问题进行浅析,并提供解决方案。 ThreadLocal 的特点: 1. 依托于线程的生命周期而存在,贯穿于整个...
3. **线程池中的ThreadLocal**: 在使用线程池时,线程可能会复用,之前的ThreadLocal值可能会影响后续的任务。因此,如果在使用线程池时依赖ThreadLocal,需要特别处理线程退出或清理ThreadLocal。 总的来说,...
但是,在Hystrix线程隔离模式下,ThreadLocal数据可能会丢失,因为Hystrix将请求放入Hystrix的线程池中去执行,这时候某个请求就有A线程变成B线程了,ThreadLocal必然消失了。 知识点3:线程切换导致ThreadLocal...
这可能导致内存泄漏,尤其是当线程池中的线程长期存活时。 2. **空指针异常**: 如果在get()之前没有调用set(),或者set()后ThreadLocal实例变为null,那么get()将会返回null,如果后续代码仍然尝试访问这个null值,...
1. **线程未正确销毁**:如果线程执行完毕后没有正确销毁或者线程池中线程长期存活,而`ThreadLocal`对象又未能及时清除,那么线程内的`ThreadLocalMap`将会持续占用内存,进而可能导致内存泄漏。 2. **...
- **谨慎在长生命周期对象中使用ThreadLocal**:避免在会存活很长时间的对象(如单例、全局服务等)中使用ThreadLocal,因为这可能导致线程长时间保持对ThreadLocal的引用,增加内存泄露的风险。 - **合理设计类结构...
例如,在doGood方法中,我们使用了try-finally块来确保ThreadLocal变量currentUid的释放,从而避免了线程池中占用的资源。 Tomcat线程池机制 Tomcat服务器使用了线程池机制来管理线程池中的线程,以提高服务器的...
下面将详细介绍ThreadLocal的工作原理、使用方法以及在Android中的实际应用。 ### 1. ThreadLocal工作原理 ThreadLocal内部实现了一个HashMap,用于存储每个线程与对应的变量副本之间的映射关系。当我们创建一个新...
如果线程池中的线程在处理完一个请求后没有被销毁,而是被复用到下一个请求,那么之前线程中的ThreadLocal变量仍然存在,这可能导致数据泄漏或错误的数据继承。 在提供的代码示例中,`...
* 请求在线程池中执行,肯定会带来任务调度、排队和上下文切换带来的开销。 * 因为涉及到跨线程,那么就存在 ThreadLocal 数据的传递问题,比如在主线程初始化的 ThreadLocal 变量,在线程池线程中无法获取。 ...
在IT行业中,线程池是高并发编程领域中不可或缺的一部分,尤其在Java中,线程池的应用非常广泛。本文将详细解析线程池的概念、重要性以及如何在实际开发中合理利用。 首先,为什么要使用线程池?线程池的主要优势...
- 在并发量非常大或者资源有限的环境中,过多使用ThreadLocal可能导致线程池中的线程复用问题,使得新线程获取到旧线程的数据,这时应谨慎使用。 总之,ThreadLocal是Java中处理线程安全问题的一种有效手段,尤其...
尤其是在使用线程池时,线程可能不会立即销毁,长时间积累可能导致内存占用过高。 5. **Entry 数组而非 Entry 对象** - `ThreadLocalMap` 使用 Entry 数组存储键值对,Entry 是 `ThreadLocal` 和其对应的值的弱...