ThreadLocal线程本地变量的使用

        使用ThreadLocal对共享变量进行封装,可使该共享变量对其他线程不可见。每个线程都会有一个该共享变量的副本,线程对自己的变量副本操作,不会影响到其他线程。以达到线程隔离,线程安全的目的。

一、用法

        在使用层面,类的静态变量或被多个线程共享的对象实例的内部属性,可通过ThreadLocal进行包装来实现线程的独立性和线程安全。

        例如以下案例:定义一个被所有线程共享的,类型为Integer的计数器。最终的计算结果均符合预期,线程之间并未发生数据被覆盖等问题。



public class ThreadLocalDemo {

    //计数器,使用ThreadLocal进行封装。
    private static ThreadLocal<Integer> count = new ThreadLocal<Integer>(){

        //初始值为0
        @Override
        protected Integer initialValue(){
            return 0;
        }
    };


    public static void main(String[] args){

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<10000000;i++){
                    int num = count.get();
                    num++;
                    count.set(num);
                }
                System.out.println("线程1的最终结果:"+count.get());
            }
        });
        thread.setName("线程1");


        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<20000000;i++){
                    int num = count.get();
                    num++;
                    count.set(num);
                }
                System.out.println("线程2的最终结果:"+count.get());
            }
        });
        thread1.setName("线程2");

        thread.start();
        thread1.start();
    }
}

         ThreadLocal是基于每个线程对象内部的一个叫做threadLocals的属性来实现的,它的类型是ThreadLocalMap(说白了就是一个Map对象)。它以ThreadLocal本本身作为键值,副本对象作为value存储,这样当每个线程调用该对象时就可以直接从自身的threadLocals属性中获取变量副本来进行操作

二、注意事项

        因为因为每个线程都包含ThreadLocal封装的共享变量副本,所以会额外占用一定的内存,随着线程数越来越大,占用的内存也会越来越大。所以在使用时,应结合真实情况,若共享变量数据太大,则建议使用synchronized关键字或java并发包下的线程安全实现,如:HashMap对应的ConcurrentHashMap、Integer对应的AtomicInteger等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值