线程上下文设计模式
? ? 线程上下文机制是参考应用或者系统上下文的机制,使每个线程拥有自己的上下文,不与其他线程共享。线程上下文机制有不同于其他上下文机制的地方,即线程的生命周期结束后,线程上下文也要回收掉,不然容易出现内存泄露。
? ? ThreadLocal为每一使用该变量的线程都提供了独立副本,可以做到线程间的数据隔离,每个线程都可以访问各自内部的副本变量。使用ThreadLocal的场景有:
-
在进行对象跨层传递的时候,可以考虑使用,避免方法多次传递,打破层次间的约束。
-
线程间的数据隔离
-
进行事务操作,用于存储线程事务信息
? ? ?ThreadLocal并不是解决多线程共享资源的技术。一般情况下,每一个线程的ThreadLocal都存储的是一个全新的对象,如果多线程的ThreadLocal存储了一个对象引用,那么其还面临着资源竞争,数据不一致的并发问题。
? ? ?使用ThreadLocal时,最常用的方法是initialValue()、set(T t)、get()。
? ? ? ? initialValue():为ThreadLocal保存的数据类型指定了一个初始化值,默认返回值为null
? ? ? ? set(T t):为ThreadLocal指定要被存储的数据。如果重写了initialValue()方法,在不调用set方法时,数据的初始值就是initialValue()方法的计算结果。
? ? ? ? get():返回当前线程在ThreadLocal中的数据备份,当前线程的数据都存放在ThreadLocalMap的数据结构中。
? ? ? ? 无论是get还是set,都不可避免的与ThreadLocalMap和Entry打交道。Entry是一个WeakReference,在没有引用的情况下,可被GC回收,避免内存泄露。
线程上下文设计模式有两种实现方式,第一种:
public class ActionContext {
private static final ThreadLocal<Context> context=ThreadLocal.withInitial(Context::new);
public static Context get() {
return context.get();
}
static class Context{
private String ip;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}
}
第二种:
public class ContextBean {
private int ip;
private String hostName;
public int getIp() {
return ip;
}
public void setIp(int ip) {
this.ip = ip;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
}
public class TaskContext {
private static final ThreadLocal<ContextBean> contextBean=ThreadLocal.withInitial(ContextBean::new);
public static ContextBean getConetxt() {
return contextBean.get();
}
public static void set(ContextBean bean) {
contextBean.set(bean);
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!