ThreadLocal类的使用

本文详细介绍了ThreadLocal类在Java中的使用,包括如何实现每个线程拥有独立的变量副本,get方法的默认值初始化以及InheritableThreadLocal类的使用。

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

关于变量值的共享,我们首先会想到public static形式变量,这种形式的变量,所有的线程都可以访问、使用该变量。如果每个线程都有自己的共享变量该如何实现?ThreadLocal类正是为了解决这个问题的。

1.ThreadLocal-隔离性

ThreadLocal类可以为每个线程绑定自己的值,在每个线程中,以私有数据形式存在。可通过set()与get()方法操作,下面验证ThreadLocal变量的隔离性

public class ThreadLocalTest {
    static ThreadLocal threadLocal = new ThreadLocal();

    public static void main(String[] args) {
        Thread threadA = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    threadLocal.set("ThreadA:"+(i+1));
                    System.out.println(threadLocal.get());
                    try {
                        sleep(200);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread threadB = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    threadLocal.set("ThreadB:"+(i+1));
                    System.out.println(threadLocal.get());
                    try {
                        sleep(200);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };
        threadA.start();
        threadB.start();
        for (int i = 0; i < 5; i++) {
            threadLocal.set("Main Thread"+(i+1));
            System.out.println(threadLocal.get());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

输出结果为

Main Thread1
ThreadB:1
ThreadA:1
ThreadA:2
ThreadB:2
Main Thread2
ThreadA:3
ThreadB:3
Main Thread3
Main Thread4
ThreadA:4
ThreadB:4
ThreadB:5
Main Thread5
ThreadA:5

可以看到不同的线程对应保存不同的值,验证了ThreadLocal变量在不同线程中的隔离性。

2.ThreadLocal get()方法默认值初始化

通过上面的例子你可能很好奇,如果不调用set() 预先设定值,直接调用get()方法会返回什么呢?

public class ThreadLocalMethod {

    static ThreadLocal threadLocal = new ThreadLocal();

    public static void main(String[] args) {
        if(threadLocal.get() == null){
            System.out.println("默认值为null");
            threadLocal.set("设置的值");
        }
        System.out.println(threadLocal.get());
    }
}

输出结果为

默认值为null
设置的值

从中可看出,默认值为null,那么设置并初始化默认值呢?

public class ThreadLocalInit {
    static InitedThreadLocal threadLocal = new InitedThreadLocal();

    public static void main(String[] args) {
        if(threadLocal.get() == null){
            System.out.println("默认值为null");
            threadLocal.set("设置的值");
        }
        System.out.println(threadLocal.get());
    }

    public static class InitedThreadLocal extends ThreadLocal{
        @Override
        protected Object initialValue() {
            return "第一次get的默认值";
        }
    }
}

输出结果为:

第一次get的默认值

3.InheritableThreadLocal类的使用

public class InheritableTest {
    static Inheritable inheritable = new Inheritable();

    public static void main(String[] args) {
        Thread threadA = new Thread(){
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("ThreadA线程中的取值:"+inheritable.get());
                    try {
                        sleep(200);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
        };
        threadA.start();
        for (int i = 0; i < 3; i++) {
            System.out.println("Main线程中的取值:"+inheritable.get());
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static class Inheritable extends InheritableThreadLocal{
        @Override
        protected Object initialValue() {
            return new Date().getTime();
        }
    }
}

输出为:

Main线程中的取值:1505115923423
ThreadA线程中的取值:1505115923423
ThreadA线程中的取值:1505115923423
Main线程中的取值:1505115923423
Main线程中的取值:1505115923423
ThreadA线程中的取值:1505115923423

可以看出使用InheritableThradLocal类,可以让子线程从父线程那取得值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值