ThreadLocal简单使用

定义:提供线程局部变量;一个线程局部变量在多个线程中,分别有独立的值(副本)。
特点:简单(开销即用),快速(无额外开销),安全(线程安全)
场景:多线程场景(资源持有,线程一致性,并发计算,线程安全等)
实现原理:java中用哈希表实现
基本API:
构造函数:ThreadLocal ()
初始化:initialValue()
访问器:get/set
回收:remove

public class Basic {
    public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
        //附初始值
        @Override
        protected Integer initialValue() {
            System.out.println("initial value run..");
            return 0;
        }
    };

    public static void main(String[] args) {
        threadLocal.set(10);
        threadLocal.remove();
        System.out.println(threadLocal.get());//若之前没有set,则会执行initialValue为其附初始值
    }

}

并发计算场景:
当有10000个请求100个线程同时请求add接口时,输出结果为10000

@RestController
@RequestMapping("/stat")
public class StatController {

    //用Set保存各个线程的值
    static Set<Val<Integer>> set = new HashSet<>();
    //因为Set可能存在于任何一个线程中,所以set.add(val)是临界区,会产生同步问题,即要加上同步锁
    synchronized static void addSet(Val<Integer> val) {
        set.add(val);
    }

    static ThreadLocal<Val<Integer>> c = new ThreadLocal<Val<Integer>>() {
        @Override
        protected Val<Integer> initialValue() {
            Val v = new Val();
            v.set(0);
            addSet(v);
            return v;
        }
    };

    @RequestMapping("/get")
    public Integer get() {
        return set.stream().map(x -> x.get()).reduce((a, x) -> a + x).get();
    }

    @RequestMapping("/add")
    public void set() throws InterruptedException {
        Thread.sleep(500);
        Val<Integer> v = c.get();
        v.set(v.get() + 1);
    }
}

参考自慕课网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值