关于ThreadLocal

注:本文参考诸葛老师的视频所记录

  • ThreadLocal 是 Java中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻,任意方法中获取缓存的数据
  • ThreadLocal 底层是通过ThreadLocalMap 来实现的,每个Thread对象(注意不是Thread对象)中都存在一个ThreadLocalMap,Map的key为ThreadLocal对象,Map的value为需要存储的值;
  • 如果在线程池中使用ThreadLocal 会造成内存泄漏,因为当ThreadLocal对象使用完之后,应该要把设置的Key,Value ,也就是Entry对象进行回收,但线程池中的线程不会回收,而线程对象是通过强引用只想ThreadLocalMap,ThreadLocalMap也是通过强引用指向Entry对象,线程不被回收,Entry对象也不被回收,从而出现内存泄漏,解决办法:在使用ThreadLocal对象之后,手动调用ThreadLocal的remove方法,手动清除Entry对象
  • ThreadLocal 经典的应用场景就是连接管理(一个线程持有一个连接,该连接对象可以在不同的方法之间传递,线程之间不共享一个连接)
public class ThreadLocalStudy {
    public static void main(String[] args) {
        Person person = new Person();

        new Thread(new Runnable() {
            @Override
            public void run() {
               person.setName("法外狂徒张三");

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:"+Thread.currentThread() + "=========" + person.getName());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                person.setName("法内狂徒罗翔");

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:"+Thread.currentThread() + "=========" + person.getName());
            }
        }).start();

        Stu stu = new Stu();

        new Thread(new Runnable() {
            @Override
            public void run() {
                stu.setName("法外狂徒张三");

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:"+Thread.currentThread() + "=========" + stu.getName());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                stu.setName("法内狂徒罗翔");

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:"+Thread.currentThread() + "=========" + stu.getName());
            }
        }).start();

    }
}
class Person{
    /**
     * 多个线程共用这个对象
     */
    private ThreadLocal<String> name = new ThreadLocal<>();

    public void setName(String name) {
        this.name.set(name);
    }

    public String getName() {
        return name.get();
    }
}

class Stu{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

使用ThreadLocal可以达到线程隔离的效果

结果对比

线程:Thread[Thread-0,5,main]=========法外狂徒张三
线程:Thread[Thread-1,5,main]=========法内狂徒罗翔
线程:Thread[Thread-2,5,main]=========法内狂徒罗翔
线程:Thread[Thread-3,5,main]=========法内狂徒罗翔
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值