使用synchronized解决线程安全问题

概述

synchronized可以用来修饰方法和代码块,其作用简要而言,就是对指定的代码块进行上锁,从而解决其存在的线程安全问题。

工作原理

用synchronized修饰的代码和指令并不影响cpu对指令的调度,被synchronized修饰的代码块仍然可以在执行执行到一半被其他指令抢占式执行,但是此时synchronized会对该指令以及涉及到的相关数据进行上锁,其他指令在同一个锁对象的情况下,想要操作这些数据必须等待前面上锁的方法或代码块释放锁,这段期间其在等待锁资源,即在阻塞状态,使用synchronized解决线程安全问题,也就是由多线程的环境转化为单线程的环境,实现代码的串行化执行

锁对象

用一个对象记录哪个线程获取了当前的锁,如果不同线程调用了同一把锁,必然会存在锁竞争的情况出现,如下图对于实例化方法而言,锁对象都是调用该方法的实例对象。而有如果synchronized修饰的是静态方法,那么其锁对象默认的则是当前的类对象。

如果synchronized修饰的是代码块,如下图,则可用用户自己指定锁对象,可以是当前对象this,也可以是某个类对象.......

总结

①只有线程A想要获取锁,则可以直接获取,不存在锁竞争②线程A和B想要同时获取同一把锁,那么只能其中一个获取锁,另一个陷入阻塞状态,等待获取锁的线程释放锁则这个线程则可进行上锁操作③如果线程A和B不是同一把锁,那么两者不存在锁竞争关系
只有锁对象是同一个对象,我们才可认为上的是同一把锁,这时候对公共数据进行操作,我们才可认为是线程安全的

synchronized的特性

①互斥:当多个线程想要调用同一把锁,必须等一个线程调用结束后,其他线程再去竞争②内存可见性:synchronized的内存可见性机制是:当一个线程实现了代码的原子性,对数据完成了读取,修改和写回操作后,其他线程可以读取主内存的数据,这时可以保证其他线程读取到的是正确的数据,通过这种方式实现内存可见③可重入:对于一个线程,如果所调用的方法链中存在多个被synchronized修饰的方法,当线程上了一个锁之后,无法再去调用其他有锁的方法,从而形成一个锁不同方法的相互等待,我们称这种锁不可重入,也称为死锁现象,而被synchronized修饰的方法,对于同一个把锁(同一个锁对象)和同一个线程,不存在互斥现象,我们称这个锁为可重入锁,synchronized形成的锁就是可重入锁,当同一个线程调用synchronized时,不仅记录了哪个线程调用了锁,同样也记录了上锁的次数,进入一个被synchronized修饰的方法则上锁次数加一。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

六子干侧开

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

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

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

打赏作者

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

抵扣说明:

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

余额充值