ThreaLocal的应用之ContextUtil

说明: ThreadLocal必须new一个对象自己使用,如果使用共享变量不能解决线程安全的问题, 它并不是为了解决线程安全而设计的,也解决不了,使用它只是为了在同一线程中传递变量

下面来看一下这个工具类:


public enum ContextUtil {
    INSTANCE;
    private final static ThreadLocal<Map<String,Object>> threadLocal = new ThreadLocal<>();
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private final String OPERATOR="operator";
    private final String OWNER="owner";

    public void clear(){
        Map<String, Object> store = loadStore();
        store.clear();
    }

    public void setOperator(Long operator){
        Map<String, Object> store = loadStore();
        store.put(OPERATOR,operator);
    }
    public Long getOperator(){
        Map<String, Object> store = loadStore();
        return (Long)store.get(OPERATOR);
    }
    public void setOwer(String owner){
        Map<String, Object> store = loadStore();
        store.put(OWNER,owner);
    }
    public String getOwner(){
        Map<String, Object> store = loadStore();
        return (String) store.get(OWNER);
    }
    //读写锁二次验证
    private Map<String,Object> loadStore(){
        lock.readLock().lock();
        Map<String, Object> store = threadLocal.get();
        if(null == store){
            // Must release read lock before acquiring write lock
            lock.readLock().unlock();
            lock.writeLock().lock();
            // Recheck state because another thread might have
            // acquired write lock and changed state before we did.
            store = threadLocal.get();
            if(null==store){
                store = new HashMap<>();
                threadLocal.set(store);
            }
            // Downgrade by acquiring read lock before releasing write lock
            lock.readLock().lock();
            // Unlock write, still hold read
            lock.writeLock().unlock();
        }
        lock.readLock().unlock();
        return store;
    }

这个工具类的主要作用是当多个用户用户登陆时, 保存下来每个用户的 “account_id”, 这样, 当这些用户做其他操作时, 后台直接从其对应线程中,就能获取到其对应的account_id.

loadStrore:
进入loadStore -> 加读锁 -> 拿到threadLocal中对应的内容 -> 内容为空 -> 释放读锁
内容不空 -> 释放读锁 -> 加写锁 -> 得到threalocal对应内容 -> 二次检查 -> 此时threadlocal中还是空 -> new一个空的hashmap并设置进去 -> 此时threadlocal中为一个空的map对象
此时threadlocal不是空, 说明其他线程已经存入了 -> 拿到当前线程的读锁 -> 释放写锁

Recheck state because another thread might have
acquired write lock and changed state before we did.
重新检查状态, 因为另一个线程可能获得了写锁并且在我们直之前改变threadlocal的值了.

关于threadload详解请点击: 查看

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值