什么时候应该使用ThreadLocal变量?
它是如何使用的?
什么时候应该使用ThreadLocal变量?
它是如何使用的?
当前回答
您必须非常小心地使用ThreadLocal模式。有一些主要的缺点,如Phil所提到的,但其中一个没有提到的是,要确保设置ThreadLocal上下文的代码不是“可重入的”。
当设置信息的代码第二次或第三次运行时,可能会发生糟糕的事情,因为线程上的信息可能会在您没有预料到的时候开始发生变化。因此,在再次设置ThreadLocal信息之前,请注意确保没有设置它。
其他回答
在多线程代码中使用类似SimpleDateFormat的类助手有三种场景,其中最好的一种是使用ThreadLocal
场景
1-通过锁或同步机制使用类似的共享对象,使应用程序变慢
线程池操作场景
2-在方法中作为局部对象使用
在线程池中,在这个场景中,如果我们有4个线程每个线程有1000个任务时间,那么我们有 创建了4000 SimpleDateFormat对象,并等待GC删除它们
3-使用ThreadLocal
在线程池中,如果我们有4个线程,我们给每个线程一个SimpleDateFormat实例 我们有4个线程,4个SimpleDateFormat对象。
不需要锁机制和对象的创建和销毁。(良好的时间复杂度和空间复杂度)
https://www.youtube.com/watch?v=sjMe9aecW_A
您必须非常小心地使用ThreadLocal模式。有一些主要的缺点,如Phil所提到的,但其中一个没有提到的是,要确保设置ThreadLocal上下文的代码不是“可重入的”。
当设置信息的代码第二次或第三次运行时,可能会发生糟糕的事情,因为线程上的信息可能会在您没有预料到的时候开始发生变化。因此,在再次设置ThreadLocal信息之前,请注意确保没有设置它。
Many frameworks use ThreadLocals to maintain some context related to the current thread. For example when the current transaction is stored in a ThreadLocal, you don't need to pass it as a parameter through every method call, in case someone down the stack needs access to it. Web applications might store information about the current request and session in a ThreadLocal, so that the application has easy access to them. With Guice you can use ThreadLocals when implementing custom scopes for the injected objects (Guice's default servlet scopes most probably use them as well).
ThreadLocals are one sort of global variables (although slightly less evil because they are restricted to one thread), so you should be careful when using them to avoid unwanted side-effects and memory leaks. Design your APIs so that the ThreadLocal values will always be automatically cleared when they are not needed anymore and that incorrect use of the API won't be possible (for example like this). ThreadLocals can be used to make the code cleaner, and in some rare cases they are the only way to make something work (my current project had two such cases; they are documented here under "Static Fields and Global Variables").
线程局部变量通常用于防止基于线程的设计中的共享 可变单例或全局变量。
在不使用连接池的情况下,它可以用于为每个线程建立单独的JDBC连接等场景。
private static ThreadLocal<Connection> connectionHolder
= new ThreadLocal<Connection>() {
public Connection initialValue() {
return DriverManager.getConnection(DB_URL);
}
};
public static Connection getConnection() {
return connectionHolder.get();
}
当您调用getConnection时,它将返回与该线程关联的连接。对于其他属性(如dateformat、事务上下文等),您不希望在线程之间共享,也可以这样做。
您也可以使用局部变量来实现相同的目的,但是这些资源通常会占用创建时间,因此您不希望在使用它们执行某些业务逻辑时一次又一次地创建它们。然而,ThreadLocal值存储在线程对象本身中,一旦线程被垃圾收集,这些值也就消失了。
这个链接很好地解释了ThreadLocal的用法。
ThreadLocal in Java had been introduced on JDK 1.2 but was later generified in JDK 1.5 to introduce type safety on ThreadLocal variable. ThreadLocal can be associated with Thread scope, all the code which is executed by Thread has access to ThreadLocal variables but two thread can not see each others ThreadLocal variable. Each thread holds an exclusive copy of ThreadLocal variable which becomes eligible to Garbage collection after thread finished or died, normally or due to any Exception, Given those ThreadLocal variable doesn't have any other live references. ThreadLocal variables in Java are generally private static fields in Classes and maintain its state inside Thread.
阅读更多:Java示例程序和教程中的ThreadLocal