多线程不安全的底层原因以及两种加锁方式的区别

如何保证多线程的安全运行

1.线程的安全性问题体现在:

  • 原子性:一个或者多个操作在 CPU 执行的过程中不被中断的特性
  • 可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到
  • 有序性:程序执行的顺序按照代码的先后顺序执行

2.导致原因:

  • 缓存导致的可见性问题
  • 线程切换带来的原子性问题
  • 编译优化带来的有序性问题

3.解决办法:

  • JDK Atomic 开头的原子类、synchronized、Lock,可以解决原子性问题
  • synchronized、volatile、Lock,可以解决可见性问题
  • Happens-Before 规则可以解决有序性问题,JVM对程序运行设定的一些规则。

两种加锁方式的区别

1.这里的两种加锁方式分别指的是synchronized关键字和Lock类。

2.这两种方式的底层实现可以看:

Lock底层原理

synchronized的底层实现

3.synchronized和Lock的区别:

  • 实现层面不一样。synchronized 是 Java 关键字,JVM 层面 实现加锁和释放锁;Lock 是一个接口,在代码层面实现加锁和释放锁,(CAS乐观锁比synchronized更底层,是CPU原语,属于操作系统层面的
  • 是否自动释放锁。synchronized 在线程代码执行完或出现异常时自动释放锁;Lock 不会自动释放锁,需要再 finally {} 代码块显式地中释放锁
  • 是否一直等待。synchronized 会导致线程拿不到锁一直等待;Lock 可以设置尝试获取锁或者获取锁失败一定时间超时
  • 获取锁成功是否可知。synchronized 无法得知是否获取锁成功;Lock 可以通过 tryLock 获得加锁是否成功
  • 功能复杂性。synchronized 加锁可重入、不可中断、非公平;Lock 可重入、可判断、可公平和不公平、细分读写锁提高效率

【Java 面试那点事】

这里致力于分享 Java 面试路上的各种知识,无论是技术还是经验,你需要的这里都有!

这里可以让你【快速了解 Java 相关知识】,并且【短时间在面试方面有跨越式提升

面试路上,你不孤单!
在这里插入图片描述

发布了154 篇原创文章 · 获赞 839 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/qq_33945246/article/details/104037104