java通过静态或非静态方法使用ThreadLocal的最佳方式是什么?
对于我的应用程序,我必须将某些信息带到应用程序的每一层(一个示例可能是为传入请求生成的唯一事务id)
因此,我计划创建一个引用ThreadLocal<ConcurrentMap<String, Object>>
的类
感激有人能帮助;我有一个困惑,出于以下方法,哪一个更好:
1。AppContext。具有静态方法的java
public final class AppContext {
private static final ThreadLocal<ConcurrentMap<String, Object>> context = new ThreadLocal<>();
public static void set(final String key, final Object value) {
// set key value in thread local
}
public static Object get(final String key) {
// get value from thread local
}
}
2。AppContext。具有非静态方法的java
public final class AppContext {
private static final ThreadLocal<ConcurrentMap<String, Object>> context = new ThreadLocal<>();
public void set(final String key, final Object value) {
// set key value in thread local
}
public Object get(final String key) {
// get value from thread local
}
}
# 1 楼答案
没有使用ThreadLocal的最佳方法。将其视为“全球变量”,以及由此产生的一切负面影响。这是地球上的一个水痘。你的应用程序中的一种癌症,总有一天会吞噬你。不惜一切代价避免它。学习如何通过适当的不可变状态,让你的线程烦恼消失
# 2 楼答案
尽管其他人可能会说,ThreadLocal变量并不是天生邪恶的,它们只是在使用时需要一些额外的注意和理解。线程安全并不是真正相关的,因为它们本质上与一个线程相关。当这些线程可能被应用程序的其他不同用户重用时,就会出现问题。在基于Java的web应用程序中,情况就是这样;但是,一次只能有一个用户/请求在该线程上运行。非常重要的一步是确保在每个请求结束时清理ThreadLocal对象
因此,为了避免不必要地为每个请求实例化一个新的上下文,我建议创建多个静态类型安全的ThreadLocal对象,所有这些对象都生活在一个“上下文”类中,这些对象以某种方式相互关联。可以使用多个上下文类来组织这些上下文项的不同组
然而,本着ThreadLocal批评者的精神,我同意ThreadLocals应该少用一些,过度使用可能是一种代码气味
以下是上述方法的一个例子
上下文类
通过Servlet过滤器管理上下文
访问上下文(例如从Servlet)
# 3 楼答案
如果
AppContext
是单例,那么静态方法是最好的方法。如果有多个AppContext
,那么应该让这些方法是非静态的