多线程 threadlocal 获取经办人信息

解决hash冲突:

在java线程中,每个线程都有一个ThreadLocalMap实例变量(如果不使用ThreadLocal,不会创建这个Map,一个线程第一次访问某个ThreadLocal变量时,才会创建)。该Map是使用线性探测的方式解决hash冲突的问题,如果没有找到空闲的slot,就不断往后尝试,直到找到一个空闲的位置,插入entry,这种方式在经常遇到hash冲突时,影响效率。

ThreadLocal为每个使用该变量的线程提供独立的变量副本(每一个线程都可以独立地改变自己的副本,不影响其它线程所对应的副本) 工作内存一样;

ThreadLocal的内部结构如下图所示
在这里插入图片描述

  • 工具类,提供一系列的方法去操作其内部类 ThreadLocalMap ;
  • 隔离Thread和ThreadLocalMap,防止程序员直接创建ThreadLocalMap(这两个类都处在java.lang包下);

如何使用ThreadLocal

在介绍ThreadLocal原理之前,首先简单介绍一下它的使用方法。

public class Main{
    //线程共享的ThreadLocal对象,该对象用于存储Integer类型的值;
    private ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
	
    public void start() {
        for (int i=0; i<10; i++) {
            new Thread(new Runnable(){
                @override
                public void run(){
                    threadLocal.set(i);
                    threadLocal.get();
                    threadLocal.remove();
                }
            }).start();
        }
    }
}
public class Person {
	String name = "zs";
}
public class ThreadLocal1 {
	volatile static Person p = new Person();
	
	public static void main(String[] args) {
		new Thread(()->{
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			System.out.println(p.name);
		}).start();
		
		new Thread(()->{
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			p.name = "ls";
		}).start();
	}
}
public class ThreadLocal2 {

	private static ThreadLocal<Person> tl = new ThreadLocal<>();
	
	public static void main(String[] args) {
		
		new Thread(()->{
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			System.out.println(tl.get());
		}).start();
		
		new Thread(()->{
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			tl.set(new Person());
		}).start();
	}
}

ThreadLocal并不维护ThreadLocalMap

提供了操作该容器的方法,如get、set、remove等。而ThreadLocal内部类ThreadLocalMap才是存储数据的容器,并且该容器由Thread维护。

ThreadLocalMap: Entry<ThreadLocal(对象),Object(对应的值)>

ThreadLocal 工具类 提供了操作threadLocals(ThreadLocalMap )的方法,如get,set,remove方法等。

Thread 的成员变量 ThreadLocalMap threadLocals,:存放别线程中所有ThreadLocal对象及其对应的值;

项目中使用

在写代码insert和update的时候,往往需要存入当前操作者的id或者name,来记录这条数据是谁更新的。

我们可以在过滤器验证权限时,从redis中拿出session信息,存放ThreadLocal中。

doFilter后,再remove ThreadLocal。

代码参考,细节省略:

public class Sample {
 
    private static final ThreadLocal<Map> ThreadLocal_Map = new ThreadLocal<Map>();
    public static void setMap(Map map) {
        ThreadLocal_Map.set(map);
    }
    
    // remove
    public static void closeMap() {
        Map map = ThreadLocal_Map.get();
        if (map != null) {
            map.clear();
            ThreadLocal_Map.remove();
        }
    }
 
    public static String getUserName() {
        Map map = ThreadLocal_Map.get();
        return map.getOrDefault("userName", "system").toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值