前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jvm源码解析(六)对锁的理解,手动实现死锁

jvm源码解析(六)对锁的理解,手动实现死锁

作者头像
JathonKatu
发布2020-10-27 14:39:16
3610
发布2020-10-27 14:39:16
举报
文章被收录于专栏:JathonKatu

并发编程中有两个重要的概念:

线程,锁

多线程是一把双刃剑,在提高程序性能的同时,

也带来了代码复杂性,对开发者的要求也提高了一个档次。

锁的出现就是为了保证多线程在同时操作一组资源时的数据一致性。

死锁是指两个线程同时占用两个资源,又在彼此等待对方释放资源

锁的概念不止存在于java语言中

比如乐观锁和悲观锁很早以前就存在于数据库中了。

锁相关的面试题:

什么是乐观锁和悲观锁,他们的应用有哪些?乐观锁有什么问题?

悲观锁

对外界的修改采取保守策略

他认为线程很容易会把数据修改掉

因此在整个数据被修改的过程中都会采取锁定状态

直到一个线程使用完,其他线程才能继续使用

乐观锁

一般情况下数据在修改时不会出现冲突

所以在数据访问之前不会加锁

只是在数据提交更改时,才会对数据进行检测

Java中的乐观锁大部分是通过CAS操作实现的

CAS是一个多线程同步的原子指令

CAS操作包含三个重要信息:内存位置、预期原值、新值

Java中Lock是乐观锁的典型案例(底层通过CAS)

CAS有可能出现ABA问题

ABA问题:

线程拿到了最初的预期值A,然而在将要进行CAS的时候,被其他线程抢占了执行权,把此值从A变成了B

然后其他的线程又将此值从B改成A,而此时的A值已经并非原来的A值了

但当初的线程在执行的时候并不知道这个情况,在他进行CAS的时候只对比了预期原值是A,就进行了修改

ABA问题的常见处理方式是增加版本号,每次修改之后都更新版本号

JDK在1.5时提供了AtomicStampedReference类,也可以解决ABA问题,此类维护了一个版本号Stamp,每次在比较时不仅比较值,还会比较版本号,就解决了ABA问题

乐观锁是在提交的时候才进行锁定的,所以不会造成死锁

什么是可重入锁?用代码如何实现?他的实现原理是什么?

可重入锁

也叫递归锁

同一线程,如果外面的函数拥有此锁后,内层的函数也可以继续获取该锁。

ReentrantLock和Synchronized都是可重入锁

可重入锁的实现原理是,在锁内部存储了一个线程标识,用于判断当前锁属于那个线程,并锁内部还有一个计数器,当线程空闲时,计数器值为0,当线程占用或重入时,计数器+1,当释放锁时,计数器-1,当计数器=0时,说明锁为空闲状态。

什么是共享锁?什么是独占锁?

独占锁

只能被单线程持有,ReentrantLock就是独占锁

可以理解为悲观锁

共享锁

可以被多线程持有,ReadWriteLock读写锁就可以允许多线程持有

可以理解为乐观锁

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JathonKatu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档