线程上下文设计模式

    线程上下文机制是参考应用或者系统上下文的机制,使每个线程拥有自己的上下文,不与其他线程共享。线程上下文机制有不同于其他上下文机制的地方,即线程的生命周期结束后,线程上下文也要回收掉,不然容易出现内存泄露。

    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=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=ThreadLocal.withInitial(ContextBean::new);

public static ContextBean getConetxt() {
return contextBean.get();
}
public static void set(ContextBean bean) {
contextBean.set(bean);
}
}

你可能感兴趣的:(2022技术栈系列,java,设计模式,java,jvm)