- 浏览: 7339170 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
什么是ThreadLocal?
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。
另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象 的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。
如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。
总之,ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。归纳了两点:
1。每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。
2。将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。
当然如果要把本来线程共享的对象通过ThreadLocal.set()放到线程中也可以,可以实现避免参数传递的访问方式,但是要注意get()到的是那同一个共享对象,并发访问问题要靠其他手段来解决。但一般来说线程共享的对象通过设置为某类的静态变量就可以实现方便的访问了,似乎没必要放到线程中。
ThreadLocal的应用场合,我觉得最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。
下面来看看ThreadLocal的实现原理(jdk1.3源码)
public class ThreadLocal<T> { /** * ThreadLocals rely on per-thread hash maps attached to each thread * (Thread.threadLocals and inheritableThreadLocals). The ThreadLocal * objects act as keys, searched via threadLocalHashCode. This is a * custom hash code (useful only within ThreadLocalMaps) that eliminates * collisions in the common case where consecutively constructed * ThreadLocals are used by the same threads, while remaining well-behaved * in less common cases. */ private final int threadLocalHashCode = nextHashCode(); /** * The next hash code to be given out. Accessed only by like-named method. */ private static int nextHashCode = 0; /** * The difference between successively generated hash codes - turns * implicit sequential thread-local IDs into near-optimally spread * multiplicative hash values for power-of-two-sized tables. */ private static final int HASH_INCREMENT = 0x61c88647; /** * Compute the next hash code. The static synchronization used here * should not be a performance bottleneck. When ThreadLocals are * generated in different threads at a fast enough rate to regularly * contend on this lock, memory contention is by far a more serious * problem than lock contention. */ private static synchronized int nextHashCode() { int h = nextHashCode; nextHashCode = h + HASH_INCREMENT; return h; } /** * Creates a thread local variable. */ public ThreadLocal() { } /** * Returns the value in the current thread's copy of this thread-local * variable. Creates and initializes the copy if this is the first time * the thread has called this method. * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) return (T)map.get(this); // Maps are constructed lazily. if the map for this thread // doesn't exist, create it, with this ThreadLocal and its // initial value as its only entry. T value = initialValue(); createMap(t, value); return value; } /** * Sets the current thread's copy of this thread-local variable * to the specified value. Many applications will have no need for * this functionality, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current threads' copy of * this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } /** * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; } /** * Create the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @param firstValue value for the initial entry of the map * @param map the map to store. */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } ....... /** * ThreadLocalMap is a customized hash map suitable only for * maintaining thread local values. No operations are exported * outside of the ThreadLocal class. The class is package private to * allow declaration of fields in class Thread. To help deal with * very large and long-lived usages, the hash table entries use * WeakReferences for keys. However, since reference queues are not * used, stale entries are guaranteed to be removed only when * the table starts running out of space. */ static class ThreadLocalMap { ........ } }
针对上面上面的代码在1.6中采用原子性操作(AtomicInteger ),更加安全。
JDK 1.6代码如下:
public class ThreadLocal<T> { /** * ThreadLocals rely on per-thread linear-probe hash maps attached * to each thread (Thread.threadLocals and * inheritableThreadLocals). The ThreadLocal objects act as keys, * searched via threadLocalHashCode. This is a custom hash code * (useful only within ThreadLocalMaps) that eliminates collisions * in the common case where consecutively constructed ThreadLocals * are used by the same threads, while remaining well-behaved in * less common cases. */ private final int threadLocalHashCode = nextHashCode(); /** * The next hash code to be given out. Updated atomically. Starts at * zero. */ private static AtomicInteger nextHashCode = new AtomicInteger(); /** * The difference between successively generated hash codes - turns * implicit sequential thread-local IDs into near-optimally spread * multiplicative hash values for power-of-two-sized tables. */ private static final int HASH_INCREMENT = 0x61c88647; /** * Returns the next hash code. */ private static int nextHashCode() { return nextHashCode.getAndAdd(HASH_INCREMENT); } /** * Returns the current thread's "initial value" for this * thread-local variable. This method will be invoked the first * time a thread accesses the variable with the {@link #get} * method, unless the thread previously invoked the {@link #set} * method, in which case the <tt>initialValue</tt> method will not * be invoked for the thread. Normally, this method is invoked at * most once per thread, but it may be invoked again in case of * subsequent invocations of {@link #remove} followed by {@link #get}. * * <p>This implementation simply returns <tt>null</tt>; if the * programmer desires thread-local variables to have an initial * value other than <tt>null</tt>, <tt>ThreadLocal</tt> must be * subclassed, and this method overridden. Typically, an * anonymous inner class will be used. * * @return the initial value for this thread-local */ protected T initialValue() { return null; } /** * Creates a thread local variable. */ public ThreadLocal() { } /** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local */ 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(); } /** * Variant of set() to establish initialValue. Used instead * of set() in case user has overridden the set() method. * * @return the initial value */ private T setInitialValue() { T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); return value; } /** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } /** * Removes the current thread's value for this thread-local * variable. If this thread-local variable is subsequently * {@linkplain #get read} by the current thread, its value will be * reinitialized by invoking its {@link #initialValue} method, * unless its value is {@linkplain #set set} by the current thread * in the interim. This may result in multiple invocations of the * <tt>initialValue</tt> method in the current thread. * * @since 1.5 */ public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); } /** * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; } /** * Create the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @param firstValue value for the initial entry of the map * @param map the map to store. */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } /** * Factory method to create map of inherited thread locals. * Designed to be called only from Thread constructor. * * @param parentMap the map associated with parent thread * @return a map containing the parent's inheritable bindings */ static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) { return new ThreadLocalMap(parentMap); } /** * Method childValue is visibly defined in subclass * InheritableThreadLocal, but is internally defined here for the * sake of providing createInheritedMap factory method without * needing to subclass the map class in InheritableThreadLocal. * This technique is preferable to the alternative of embedding * instanceof tests in methods. */ T childValue(T parentValue) { throw new UnsupportedOperationException(); } /** * ThreadLocalMap is a customized hash map suitable only for * maintaining thread local values. No operations are exported * outside of the ThreadLocal class. The class is package private to * allow declaration of fields in class Thread. To help deal with * very large and long-lived usages, the hash table entries use * WeakReferences for keys. However, since reference queues are not * used, stale entries are guaranteed to be removed only when * the table starts running out of space. */ static class ThreadLocalMap { ... } }
可以看到ThreadLocal类中的变量只有这3个int型:
/** * ThreadLocals rely on per-thread linear-probe hash maps attached * to each thread (Thread.threadLocals and * inheritableThreadLocals). The ThreadLocal objects act as keys, * searched via threadLocalHashCode. This is a custom hash code * (useful only within ThreadLocalMaps) that eliminates collisions * in the common case where consecutively constructed ThreadLocals * are used by the same threads, while remaining well-behaved in * less common cases. */ private final int threadLocalHashCode = nextHashCode(); /** * The next hash code to be given out. Updated atomically. Starts at * zero. */ private static AtomicInteger nextHashCode = new AtomicInteger(); /** * The difference between successively generated hash codes - turns * implicit sequential thread-local IDs into near-optimally spread * multiplicative hash values for power-of-two-sized tables. */ private static final int HASH_INCREMENT = 0x61c88647;
而作为ThreadLocal实例的变量只有 threadLocalHashCode 这一个,nextHashCode 和HASH_INCREMENT 是ThreadLocal类的静态变量,实际上HASH_INCREMENT是一个常量,表示了连续分配的两个ThreadLocal实例的threadLocalHashCode值的增量,而nextHashCode 的表示了即将分配的下一个ThreadLocal实例的threadLocalHashCode 的值。
可以来看一下创建一个ThreadLocal实例即new ThreadLocal()时做了哪些操作,从上面看到构造函数ThreadLocal()里什么操作都没有,唯一的操作是这句:
private final int threadLocalHashCode = nextHashCode();
那么nextHashCode()做了什么呢:
/** * Returns the next hash code. */ private static int nextHashCode() { return nextHashCode.getAndAdd(HASH_INCREMENT); }
因此ThreadLocal实例的变量只有这个threadLocalHashCode,而且是final的,用来区分不同的ThreadLocal实例,ThreadLocal类主要是作为工具类来使用,那么ThreadLocal.set()进去的对象是放在哪儿的呢?
看一下上面的set()方法,两句合并一下成为
/** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } /** * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
这个ThreadLocalMap 类是ThreadLocal中定义的内部类,但是它的实例却用在Thread类中:
也就是将该ThreadLocal实例作为key,要保持的对象作为值,设置到当前线程的ThreadLocalMap 中,get()方法同样大家看了代码也就明白了,
map都是放在每个线程中的,以threadLocal为key,所不同的是,在1.3中这个map是个普通的HashMap,而1.4和1.5中是个ThreadLocalMap类,一个明显的特征是其中的Entry用到了弱引用WeakReference 类,但我感觉这个WeakReference的用法在这里并不能起到应有的作用。
另外想到一个把map放到各自线程中带来的好处是 因为各线程访问的map是各自不同的map,所以不需要同步,速度会快些;而如果把所有线程要用的对象都放到一个静态map中的话 多线程并发访问需要进行同步。
Synchronized还是ThreadLocal?
ThreadLocal以空间换取时间,提供了一种非常简便的多线程实现方式。因为多个线程并发访问无需进行等待,所以使用ThreadLocal会获得更大的性能。虽然使用ThreadLocal会带来更多的内存开销,但这点开销是微不足道的。因为保存在ThreadLocal中的对象,通常都是比较小的对象。另外使用ThreadLocal不能使用原子类型,只能使用Object类型。ThreadLocal的使用比synchronized要简单得多。
ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。
Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。
当然ThreadLocal并不能替代synchronized,它们处理不同的问题域。Synchronized用于实现同步机制,比ThreadLocal更加复杂。
ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。 而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。 由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用。 概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。 Spring使用ThreadLocal解决线程安全问题 我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、 TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。 一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程,如图9‑2所示: 图1同一线程贯通三层 这样你就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有关联的对象引用到的都是同一个变量。
详细请看百度百科:
发表评论
-
Mule ESB 学习笔记(20)Mule和Spring httpinvoker的整合
2013-08-28 13:59 3766mule的配置文件: <?xml version=& ... -
Mule ESB 学习笔记(19)Mule和RSS的整合
2013-08-28 10:08 2601定时扫描特定目录的rss文件: <?xml vers ... -
Mule ESB 学习笔记(18)Mule和ATOM的整合
2013-08-27 20:00 2621定时读取特定文件的rss文件: <?xml ... -
Mule ESB 学习笔记(17)Mule和JMX的整合
2013-08-27 16:48 4065Agent的实现: package com.easyway ... -
Mule ESB 学习笔记(16)CXF SOAP基于SAML的验证的配置
2013-08-27 15:19 3805mule的配置 <mule xmlns:core=& ... -
Mule ESB 学习笔记(15)CXF SOAP基于JKS的验证的配置
2013-08-27 14:57 3876mule的配置如下: <mule xmlns:cor ... -
Mule ESB 学习笔记(14)CXF SOAP基于UsernameToken的验证
2013-08-27 14:16 7955简单需求: 针对在webservice ... -
Mule ESB 学习笔记(13)CSV数据文件到数据库
2013-08-26 17:54 7047简单需求: ... -
Mule ESB 学习笔记(12)JSON转换器的使用
2013-08-26 13:54 9098在许多情况下,可能需要把类转换为js ... -
Mule ESB 学习笔记(11)Web Service Proxy
2013-08-24 19:32 6630一、WebSevice Proxy 简介 ... -
Mule ESB 学习笔记(10)mule事务配置
2013-08-23 16:36 6240在mule的事务可能为jdbc事务,jms事务 ... -
Mule ESB 学习笔记(9)mule配置常用节点解释
2013-08-23 13:27 34461 Mule-config.x ... -
Mule ESB 学习笔记(8)mule和jersey的整合使用
2013-08-23 11:20 3947在项目常用jesery作为rest ... -
Mule ESB 学习笔记(7)服务调用
2013-08-23 10:44 18915一. 服务调用 1. Mule实现并提供Web Servi ... -
Mule ESB 学习笔记(6)配置模式
2013-08-23 10:42 4778为了节省时间,就不翻译了,摘抄重点总结 ... -
Mule ESB 学习笔记(5)异步请求-响应方式
2013-08-22 15:32 35915.4 异步请求-响应方式 异步请求-响应方式即请求方调用 ... -
Mule ESB 学习笔记(4)同步方式
2013-08-22 15:19 42555.3 同步方式 同步方式即请求方调用 ... -
JBOSS EJB3项目启动执行一个任务
2013-08-06 22:26 3845在jboss的项目中,jboss启动 ... -
Jboss @Service的使用
2013-08-06 21:59 1995Jboss有一个扩展的annotation——@Servic ... -
julian Date 计算 和实现
2013-08-01 09:32 4451Qt库里CBSDate类的内部实现用_jd成员进行计算、比较 ...
相关推荐
总结:`ThreadLocal` 是一个强大的工具,但在使用时必须谨慎,尤其是在多线程环境中,如 Tomcat 这样的 Web 容器。如果不正确地管理 `ThreadLocal` 的生命周期,可能导致类加载器级别的内存泄漏。理解 `ThreadLocal`...
通过以上分析,我们可以看到`ThreadLocal`为多线程环境下的编程提供了一种简洁优雅的解决方案。它不仅能够避免复杂的同步问题,还能有效地管理线程间的变量隔离。理解`ThreadLocal`的工作原理及其使用方法,可以帮助...
3. **日志记录**:在多线程环境中,`ThreadLocal`可以用于维护每个线程的日志上下文,如线程ID、用户名等,便于日志信息的记录和分析。 4. **性能优化**:在某些计算密集型应用中,`ThreadLocal`可以用于缓存线程...
总结来说,Java线程编程中的ThreadLocal类提供了一种高效、便捷的方式来实现线程间的隔离数据,但同时也需要开发者注意其潜在的内存泄漏风险。正确理解和使用ThreadLocal,能够帮助我们编写出更加健壮、高效的并发...
ThreadLocal的实现原理可以总结为:每个线程都有一个自己的ThreadLocalMap,用于存放线程的本地变量;ThreadLocal的set、get、remove方法都是基于ThreadLocalMap的操作。 ThreadLocal的优点是可以解决多线程访问...
### 知识点详解:Java.lang.ThreadLocal 类 #### 一、概述 **ThreadLocal** 并非线程的一种特殊实现形式,而是一种为每个线程...理解 ThreadLocal 的工作原理和应用场景对于编写高效可靠的多线程应用程序至关重要。
java并发编程总结,包括多线程安全机制分析总结,Unsafe源码分析总结,并发工具类总结,ThreadLocal原理和使用,Fork/Join框架使用总结,同步容器和并发容器源码分析
### MAT Java Dump 文件分析 #### 一、MAT工具简介与使用方法 MAT(Memory Analyzer ...结合以上分析方法,MAT为Java开发者提供了一套完整的内存分析解决方案,能够帮助他们更好地理解和优化应用程序的内存使用情况。
- **Histogram** 显示 ThreadLocal 和自定义类 `bingo.persister.dao.Daos` 占用了大量内存。 - **Dominator Tree** 指出 Quartz 定时器的工作线程(共 10 个)占用了大量内存。 - **Top Consumers** 显示了内存中...
总结,Hessian作为高效的RPC框架,虽然没有内置获取客户端信息的功能,但通过分析其源码并适当扩展,我们能够实现这一需求。需要注意的是,直接修改开源库的源码可能带来维护上的困扰,因此在可行的情况下,推荐使用...
总结来说,Activiti的工作流源码分析揭示了它在架构设计上的优秀之处,特别是在使用命令模式作为基础开发模型时,对职责分离和解耦所带来的益处。同时,Activiti基于Spring、ibatis等开源中间件的架构选择,为开发...
为了解决这些问题,可以使用线程局部变量(`ThreadLocal`)、锁分离策略(如读写锁`ReentrantReadWriteLock`)、原子变量(`Atomic*`类)等技术。 最后,Java并发编程还涉及线程池的使用,通过预先创建一定数量的...
### 关于Java内存泄漏 #### 一、Java内存管理机制 Java的一大特色在于其自动化的内存管理机制,这主要依赖于垃圾收集器(Garbage Collection, GC)来自动完成对象的内存分配与回收。尽管这一特性极大地减轻了...
* 多线程:ThreadLocal、lock 和 sync 区别、AQS 原理、CountDownLatch 和 CyclicBarrier 的区别、volatile 的用法 * 数据库:mysql 索引(聚集索引、非聚集索引)、执行计划、count1*区别、MVCC 和事务隔离级别的...
可以使用 .NET 提供的性能计数器(Performance Counters)或者第三方工具(如 dotTrace、ANTS Profiler 等)来分析 CPU 使用率、线程数、内存占用等指标,找出性能瓶颈并进行优化。 此外,对于服务端,你还需要关注...
除此之外,JavaWeb、数据库、Spring框架、Spring Boot、数据结构与算法、JVM、设计模式、Linux、SpringCloud、中间件技术、Vue前端框架、计算机网络、性能调优、系统设计、源码分析、计算机理论和阅读高质量代码的...
总结来说,`Handler`、`Looper`和`MessageQueue`构成了Android异步消息处理的基础框架。`Handler`用于发送和处理消息,`Looper`负责消息循环,`MessageQueue`则是消息的存储容器。在主线程中,`sMainLooper`使得大...
5. **使用ThreadLocal**:为每个线程创建独立的变量副本,避免线程间共享变量的问题。 #### 八、案例分析 以给定的部分内容为例,其中涉及到了线程池的使用。具体来说,通过`ObjectPoolFactory`类来管理对象池,...
1. **污点传播技术**:通过在请求中添加污点标记(如魔数),利用Tomcat线程机制和ThreadLocal,确保污点路径的唯一性,以追踪敏感数据在整个应用程序中的流动情况。 2. **栈签名算法**:在运行时,将栈信息转换为...