多线程的ThreadLocal、ReentrantLock、volatile、Synchronized

  1. ThreadLocal:ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,防止自己的变量被其它线程篡改。

    Spring框架里面就是用的ThreadLocal来实现这种隔离,主要是在TransactionSynchronizationManager这个类里面

    简单原理:每个线程Thread都维护了自己的threadLocals变量,所以在每个线程创建ThreadLocal的时候,实际上数据是存在自己线程Thread的threadLocals变量里面的,别人没办法拿到,从而实现了隔离

  2. ReentrantLock: 可重入锁

    1. void lock():加锁,如果锁已经被别人占用了,就无限等待。 大规模得在复杂场景中使用,是有可能因此死锁的。因此,使用这个方法得非常小心。
    2. boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException:尝试获取锁,等待timeout时间。同时,可以响应中断。 (可以有效预防发生死锁 )
    3. void unlock() :释放锁
    4. 重入锁使得同一个线程可以对同一把锁,在不释放的前提下,反复加锁,而不会导致线程卡死。因此,如果我们使用的是重入锁,你唯一需要保证的,就是unlock()的次数和lock()一样多
    5. 锁使用完后,千万不要忘记把它释放了
  3. volatile

    首先关联到的就是JMM(Java Memory Model)M6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDMwMDEzOQ==,size_16,color_FFFFFF,t_70)
    线程对变量的所有的操作(读,取)都在工作内存中完成,从而导致了 可见性问题 ,及一个线程修改了主内存中的变量值后,其他线程还是使用的旧值,导致不一致问题,从而引出了validate。

    概述:

    1、怎么发现数据是否失效呢?嗅探机制,会导致总线风暴问题

    2、禁止指令重排序(通过内存屏障实现)

    3、无法实现原子性(可以使用原子操作类避免如: AtomicInteger 等)

    4、 volatile提供了可见性(MESI缓存一致性实现),任何一个线程对其的修改将立马对其他线程可见,volatile属性不会被线程缓存,始终从主 存中读取

  4. synchronized

    1、可重入性

    synchronized锁对象的时候有个计数器(存在对象的 对象头 中),他会记录下线程获取锁的次数,在执行完对应的代码块之后,计数器就会-1,直到计数器清零,就释放锁了

    2、不可中断性

    不可中断就是指,一个线程获取锁之后,另外一个线程处于阻塞或者等待状态,前一个不释放,后一个也一直会阻塞或者等待,不可以被中断。

    值得一提的是,Lock的tryLock方法是可以被中断的

    3、同步代码块

    monitorenter 代码块 monitorexit

    4、同步方法

    特殊标志位 ACC_SYNCHRONIZED
    同步方法的时候,一旦执行到这个方法,就会先判断是否有标志位,然后,ACC_SYNCHRONIZED会去隐式调用刚才的两个指令:monitorenter和monitorexit

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码厚炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值