关于ThreadLocal的使用

本文通过一个具体的示例详细介绍了ThreadLocal的基本用法及其在多线程环境中的优势。通过mmain.java、SQLSearch.java和ThreadLocalUtils.java三个类的配合,演示了如何为每个线程分配独立的变量副本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

             ThreadLocal 是为了更好的写多线程,而使用的变量,个人理解不是通常利用ThreadLocal变量来处理线程同步关系的。而是为了方便书写代码。

参考了博文:原博文 ,我又将其冗余的部分修改了,为了更好理解,下面做一些必要的说明。

总共有三个类:mmain.java   SQLSearch.java ThreadLocalUtils.java

             mmain.java 就是java的运行主类(包含main的方法),SQLSearch.java 是为了获取到调用该方法所对应的线程变量,并显示信息。 ThreadLocalUtils.java 定义了用来保存各个线程所持有变量的集合。

              源码如下:

ThreadLocalUtils.java

public class ThreadLocalUtils{
    public static final ThreadLocal<String> DATA = new ThreadLocal<String>();
}

SQLSearch.java

public class SQLSearch{
    public String run(){
        return search(ThreadLocalUtils.DATA.get()); //将会获得对应的线程的String对象,也就是在ThreadLocal尖括号之间的类型  
    }

    private String search(String name){
        String result = null;
        if(name.equals("S")){
            result = (name+":165");
        }
        if(name.equals("M")){
            result = (name+":170");
        }
        if(name.equals("L")){
            result = (name+":175");
        }
        if(name.equals("XL")){
            result = (name+":180");
        }
        if(name.equals("XXL")){
            result = (name+":185+");
        }
        return result;
        }
}
mmain.java :

public class mmain{
    static String[] names = new String[]{"S","M","L","XL","XXL"};     //衣服的尺码
    static int index = 0;                                             //为了分别设置线程名称

    public static void main(String args[]){
        for(int i = 0; i < names.length; i++){
            Thread t = new Thread(){
                public void run(){
                    ThreadLocalUtils.DATA.set(this.getName());       //设置当前线程的名称
                    System.out.println(new SQLSearch().run());       //利用SQLSearch中run方法获取到当前线程的线程名
                }
            };
            t.setName(names[index++]);                               //将尺码的名称依次设置为线程名
            t.start();                                               //启动线程
        }
    }
}
执行的结果如下:

sely@com:~/sylinux/ThreadLocal$ java mmain
S:165
M:170
L:175
XL:180
XXL:185+
代码执行的流程:

         1.  执行main函数,进入for循环,生成了第一个thread()

         2.  设置第一个thread的线程名,index为0,所以设置的线程名为“S”

         3.  执行线程的start方法,就会调用run()方法,也就是重写的run方法体,方法体执行了ThreadLocalUtils.DATA.set(this.getName());

              DATA是static属性,属于ThreadLocalUtils这个类的,不属于任何它的实例化对象所有,可以用类名.属性名的方法直接调用。DATA这个变量是ThreadLocal对象,

              <T>之间就是这个变量所保存的数据类型。

         4.  ThreadLocal<T>类提供了一下的方法:

                     T  get()  :  Returns the value in the current thread's copy of this thread-local variable.

                     protected  T  initialValue() :   Returns the current thread's "initial value" for this thread-local variable.

                     void   remove()  :  Removes the current thread's value for this thread-local variable.

                     void   set(T value) : Sets the current thread's copy of this thread-local variable to the specified value.

         5.  代码利用DATA.set()方法,就会将当前线程的名称(String类型)设置到DATA中去,调用set的线程,此时就是第一个创建的线程,所以set进DATA就是“S”

         6.  第二次利用set()方法又会设置当前线程名,  这时同样调用的是第二个线程的getName(),设置到DATA中。

               .........

         7.  设置过程中,又利用new SQLSearch()对象的run方法,来取出它保存在DATA中的String,调用 ThreadLocalUtils.DATA.get()方法,就会获得调用这个方法所属于线程开始设置的变量。跟set差不多,所以每次get都能够区分开线程所拥有的值了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值