ThreadLocal使用及方法介绍测试

底层原理

1.1.ThreadLocal是java中所提供的线程本地存储机制,可以利用该机制将数据缓存到数据内部,该线程可以任务获取缓存中的数据
1.2.ThreadLocal底层是通过ThreadLocalMap来实现的,每个thread对象中都存在一个ThreadLocalMap,ThreadLocalMap的key是ThreadLocal对象,
ThreadLocalMap的value是需要缓存的值
1.3.如果在线程池中使用ThreadLocal会造成内存泄漏,因为线程池里面的线程使用不会立即销毁,
导致entry对象不会进行回收,所以使用完之后要调用ThreadLocal的方法手动清理entry对象
1 4.ThreadLocal经典的应用场景就是连接管理(一个线程持有一个连接,该连接对象在不同的方法之间进行传递,线程之间不共享一个连接)

方法介绍

 get()获取ThreadLocal中当前线程共享变量的值
 set()设置ThreadLocal中当前线程共享变量的值
 remove()移除ThreadLocal中当前线程共享变量的值
 initialValue() ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值

工具类

import java.util.HashMap;
import java.util.Map;

/**
 * @author syl
 */
public class ThreadLocalUtils {
    /**
     * private static可以排除ThreadLocal的弱引用,
     */
    private static final ThreadLocal<Map<String,Object>> THREAD_LOCAL=new ThreadLocal(){
        @Override
        protected Object initialValue() {
            System.out.println("值为空");
            return null;
        }
    };

    /**
     * 通过key获取数据
     * @param key
     * @return Object
     */
    public static Object getData(String key){
        Map map= THREAD_LOCAL.get();
        if (map==null){
            return null;
        }
        return map.get(key);
    }

    /**
     * 设置值
     * @param key
     * @param value
     */
    public static void setData(String key,Object value){
        Map map= THREAD_LOCAL.get();
        if (map==null){
            map=new HashMap<String,Object>();
            map.put(key,value);
            THREAD_LOCAL.set(map);
        }
        map.put(key, value);
    }

    /**
     * 清空当前线程所有的变量
     */
    public static void remove(){
        THREAD_LOCAL.remove();
    }

    /**
     * 清除当前线程指定的变量
     * @param key
     */
    public static void remove(String key){
        Map map= THREAD_LOCAL.get();
        if (map!=null){
            map.remove(key);
        }
    }

    public static void main(String[] args) {
        //测试线程之间数据不共享,只能从自己的线程获取/删除/设置数据

        //在不同线程之间调用
        twoThread();

        //在同一线程调用
        oneThread();
    }

    /**
     * 在同一线程之间调用
     */
    private static void oneThread() {
        new Thread("3"){
            @Override
            public void run() {
               main1();
               main2();
            }
        }.start();
    }

    /**
     * 在不同线程之间调用
     */
    private static void twoThread() {
        Thread t1= new Thread("1") {
            @Override
            public void run() {
                main1();
            }
        };

        Thread t2= new Thread("2") {
            @Override
            public void run() {
                try {
                    //让线程顺序执行,让join的线程先执行完再执行当前线程
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                main2();
            }
        };
        t1.start();
        t2.start();
    }

    public  static void main1() {
        ThreadLocalUtils.setData("a", "zyp");
        String name = Thread.currentThread().getName();
        System.out.println("当前线程名"+name);
        Object a = ThreadLocalUtils.getData("a");
        System.out.println(a);
    }

    public static void main2() {
        String name = Thread.currentThread().getName();
        System.out.println("当前线程名"+name);
        Object a = ThreadLocalUtils.getData("a");
        if (a==null){
            System.out.println("不同线程之间数据不共享");
        }else {
            System.out.println("同一线程数据共享,值为"+a);
        }
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值