线程安全问题

线程安全问题

线程安全的意思,是在多线程各种随机的调度顺序下,代码都没有bug,都能够符合预期的方式来执行

如果在多线程各种随机的调度顺序下,代码出现bug,此时就认为是线程不安全的

线程不安全的原因:

1、抢占式执行,多个线程的执行调度过程,可以视为是没有规律的随机的

2、多个线程同时修改同一个变量

3、修改操作不是原子的---原子表示不可分割的最小单位

4、内存可见性问题---JVM的代码优化引入的bug

5、指令重排序---如果在单线程情况下,JVM、CPU指令集会对指令进行优化,按照一个优化的顺序去调度执行

解决线程安全问题需要使用到synchronized关键字

synchronized关键字

synchronized 会起到互斥效果,某个线程执行到某个对象的 synchronized 中时,其他线程如果也执行到同一个对象 synchronized 就会阻塞等待

在java中,任意的对象,都可以作为锁对象,在使用锁的时候,一定要明确是针对哪个对象加锁,直接影响到后面锁操作是否会触发阻塞

synchronized这个操作将"并发"变成了"串行",确实会减慢执行效率

进入 synchronized 修饰的代码块, 相当于 加锁,加锁期间其他线程执行到这里会线程阻塞

退出 synchronized 修饰的代码块, 相当于 解锁,线程阻塞的线程开始加锁执行此代码块

synchronized修饰方法(修饰方法相当于锁对象就是this):

修饰符 synchronized 返回值类型 方法名(参数) {

}

synchronized修饰代码块(如果一个方法中有些代码需要加锁有些不需要,就可以使用代码块):

synchronized (任意对象,例如this) {

}

如果对一个线程的同一个代码区域重复加锁(加了两把锁,方法一把,代码块一把),就有可能会出现死锁的现象,因为第二把锁永远也等不到第一把锁执行结束(解锁)

针对上述情况,不会产生死锁的话,这样的锁就称之为"可重入锁",会产生死锁的话,这样的锁就称之为"不可重入锁"

synchronized关键字是可重入的(也就是如果重复加锁,重复的锁会被忽略掉),这是因为其内部维护了一个计数器,来衡量啥时候是真加锁/解锁,啥时候是重复的锁需要被忽略掉

synchronized关键字是一个非常优秀的设计,无论是正常执行完代码块还是触发异常,都会触发解锁操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值