Java多线程学习(二)ThreadLocal原理和作用

在多线程中,遇到线程安全性的问题,一般有两种解决办法:

一、使用同步控制的synchronized,将并发变成同步,是一种时间换空间的办法,有时候效率较低。

二、使用ThreadLocal线程本地存储,为各个线程分配一个变量的副本,每个线程都是操作的自己的变量,读写不会干扰到其他线程,实现了数据隔离,是一种空间换时间的办法。不过因为ThreadLocal为每个线程都分配了一份拷贝,如果不及时回收,可能会造成内存泄漏。

ThreadLocal是将线程与对象绑定在一起,每个线程操作的都是自己独立的一份拷贝,通过getter和setter对变量进行读写,所以每次都会读到线程的最新值,保证了可见性。

ThreadLocal类中的方法:

public T get() { }
public void set(T value) { }
public void remove() { }
protected T initialValue() { }

get是获取变量值,并且在获取值之前一定要先set,否则就调用setInitialValue方法返回value。get方法底层的实现是基于一个ThreadLocalMap,将当前线程传递进去获取到一个ThreadLocalMap,然后通过键值对方式获取信息。如果两者都没有,会返回一个null。

set为变量赋值。每个ThreadLocal修饰的变量只有一个,set赋值过程中,后面的会覆盖前面赋过的值。

remove移除当前线程中的变量副本。

initialValue为所有线程的变量副本赋一个初始值。

public class ThreadLocalTest {
    private ThreadLocal<String> threadLocalString = new ThreadLocal<String>(){
        protected String initialValue() {
            return Thread.currentThread().getName();
        }
    };
    public void set(String s1,String s2){
        threadLocalString.set(s1);
        threadLocalString.set(s2);
    }
    public String get(){
        return threadLocalString.get();
    }

    public static void main(String[] args) {
        ThreadLocalTest test = new ThreadLocalTest();
        new Thread(new Runnable() {
            public void run() {
                //test.set("11111","11!!!");
                System.out.println(test.get());
            }
        }).start();
        new Thread(new Runnable() {
            public void run() {
                test.set("22222","222!!!");
                System.out.println(test.get());
            }
        }).start();
    }
}

 

运行结果:

 

可以看到后面的值覆盖掉了前面的,并且将set注释掉之后,get返回的是初始化的数据,并且两个线程的变量相互不影响。

 

ThreadLocal最常见的用途就是在分配数据库链接中。单线程情况下,getConnection是没有问题的,但是在多线程情况下,可能一个线程还在使用connection,另一个线程就调用了close方法将链接关闭了,这样就会有安全性问题。如果使用ThreadLocal,为每个线程都分配一个connection,各个线程互不影响,就不会出现安全性问题了。

还有就是用在session管理中,每个线程有各自的session,互不影响。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值