线程并发安全问题解决方案

线程并发安全问题解决方案


目录

问题

解决方案

保证并发安全的三大特性

1、synchronized

2、Lock

3、CAS

4、volatile

5、JDK并发工具

6、并发安全的集合

7、原子工具类


问题

并发安全是多个线程对共享资源进行访问操作,共享数据能被正确处理,那么如何保证线程的并发安全呢?

解决方案

保证并发安全的三大特性

1 原子性

原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉

例如i=i+1不是原子操作,此时并发调用该指令时,i值不会如我们预想那样进行赋值,这便是原子性问题

2 可见性

可见性是指当一个线程修改了共享变量后,其他线程能够立即得知这个修改

可参考4.1 JMM抽象内存模型,主存与工作内存不一致,便会引起可见性问题

3 有序性

为了性能优化,编译器和处理器会进行指令重排序;也就是说java程序天然的有序性可以总结为:如果在本线程内观察,所有的操作都是有序的;如果在一个线程观察另一个线程,所有的操作都是无序的

1、synchronized

保证原子性、可见性、有序性

synchronized通过对象的对象头中的MarkWord实现,其锁升级过程步骤如下

1.初期锁对象刚创建时,还没有任何线程来竞争,对象的Mark Word是下图的第一种情形,这偏向锁标识位是0,锁状态01,说明该对象处于无锁状态(无线程竞争它)。

2.当有一个线程来竞争锁时,先用偏向锁,表示锁对象偏爱这个线程,这个线程要执行这个锁关联的任何代码,不需要再做任何检查和切换,这种竞争不激烈的情况下,效率非常高。这时Mark Word会记录自己偏爱的线程的ID,把该线程当做自己的熟人。如下图第二种情形。

3.当有两个线程开始竞争这个锁对象,情况发生变化了,不再是偏向(独占)锁了,锁会升级为轻量级锁,两个线程公平竞争,通过CAS对对象头进行设置,哪个线程先占有锁对象并执行代码,锁对象的Mark Word就执行哪个线程的栈帧中的锁记录。如下图第三种情形。

4.如果竞争的这个锁对象的线程更多,导致了更多的切换和等待,JVM会把该锁对象的锁升级为重量级锁,这个就叫做同步锁,这个锁对象Mark Word再次发生变化,会指向一个监视器对象,这个监视器对象用集合的形式,来登记和管理排队的线程。如下图第四种情形。

2、Lock

3、CAS

4、volatile

用于保证变量的可见性与有序性,不保证原子性。

使用volatile修饰的变量,虚拟机将不会对指令重排序,同时值的读写将直接对主内存进行操作。

5、JDK并发工具

5.1、CyclicBarrier

5.2、CountDownLatch

5.3、Semaphore

6、并发安全的集合

6.1、List

6.2、Map

6.3、Set

6.4、Queue

7、原子工具类

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值