线程是否要锁住同步资源
- 锁住 悲观锁
- 不锁住 乐观锁
锁住同步资源失败 线程是否要阻塞
- 阻塞
- 不阻塞自旋锁,适应性自旋锁
多个线程竞争同步资源的流程细节有没有区别
- 不锁住资源,多个线程只有一个能修改资源成功,其它线程会重试无锁
- 同一个线程执行同步资源时自动获取资源偏向锁
- 多个线程竞争同步资源时,没有获取资源的线程自旋等待锁释放 轻量级锁
- 多个线程竞争同步资源时,没有获取资源的线程阻塞等待唤醒 重量级锁
4.多个线程竞争锁时是否要排队
- 排队公平锁
- 先尝试插队,插队失败在排队非公平锁
一个线程的多个流程能不能获取同一把锁
- 能 可重入锁
- 不能非可重入锁
多个线程能不能共享一把锁
- 能 共享
- 不能排他锁
悲观锁与乐观锁
悲观锁与乐观锁时一种广义的概念,体现的是看待线程同步的不同角度。
悲观锁
悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,在获取数据的时候会先加锁,确保数据不会被别的线程修改。 锁实现:synchronized
接口Lock
的实现类 适用场景:写操作多,先加锁可以保证写操作时数据正确。
乐观锁
乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。 锁实现:CAS
算法,例如AtomicInteger
类的原子自增时通过CAS
自旋实现。 适用场景:读操作较多,不加锁的特点能够使其读操作的性能大幅度提升。 乐观锁的执行流程: 线程A获取到数据以后直接操作,操作完数据以后准备更新同步资源,更新之前会先判断内存中同步资源是否被更新: 1.如果没有被更新,更新内存中同步资源的值。 2.如果同步资源被其他线程更新,根据实现方法执行不同的操做(报错or重试)。
CAS算法
全名:Compare And Swap(比较并交换) 无锁算法:基于硬件原语实现,在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。 jdk中的实现:java.util.concurrent包中的原子类就是通过CAS来实现了乐观锁。 算法涉及到的三个操作数:
需要读写的内存值V
进行比较的值A
要写入的新值的B
CAS存在的问题
1.ABA问题 线程1准备用CAS将变量的值由A替换为B,在此之前,线程2将变量的值由A替换为C,又由C替换为A,然后线程1执行CAS时发现变量的值仍然为A,所以CAS成功。但实际上这时的现场已经和最初不同了,尽管CAS成功,但可能存在潜藏的问题。 举例:一个小偷,把别人家的钱偷了之后又还了回来,还是原来的钱吗,你老婆出轨之后又回来,还是原来的老婆吗?ABA问题也一样,如果不好好解决就会带来大量的问题。最常见的就是资金问题,也就是别人如果挪用了你的钱,在你发现之前又还了回来。但是别人却已经触犯了法律。 但是jdk已经解决了这个问题。 想追下源码来着,但是一追发现直接到c了。
2.循环时间长开销大 3.只能保证一个共享变量的原子操作
最后
为什么我不完全主张自学?
①平台上的大牛基本上都有很多年的工作经验了,你有没有想过之前行业的门槛是什么样的,现在行业门槛是什么样的?以前企业对于程序员能力要求没有这么高,甚至十多年前你只要会写个“Hello World”,你都可以入门这个行业,所以以前要入门是完全可以入门的。
②现在也有一些优秀的年轻大牛,他们或许也是自学成才,但是他们一定是具备优秀的学习能力,优秀的自我管理能力(时间管理,静心坚持等方面)以及善于发现问题并总结问题。
如果说你认为你的目标十分明确,能做到第②点所说的几个点,以目前的市场来看,你才真正的适合去自学。
除此之外,对于绝大部分人来说,报班一定是最好的一种快速成长的方式。但是有个问题,现在市场上的培训机构质量参差不齐,如果你没有找准一个好的培训班,完全是浪费精力,时间以及金钱,这个需要自己去甄别选择。
我个人建议线上比线下的性价比更高,线下培训价格基本上没2W是下不来的,线上教育现在比较成熟了,此次疫情期间,学生基本上都感受过线上的学习模式。相比线下而言,线上的优势以我的了解主要是以下几个方面:
①价格:线上的价格基本上是线下的一半;
②老师:相对而言线上教育的师资力量比线下更强大也更加丰富,资源更好协调;
③时间:学习时间相对而言更自由,不用裸辞学习,适合边学边工作,降低生活压力;
④课程:从课程内容来说,确实要比线下讲的更加深入。
应该学哪些技术才能达到企业的要求?(下图总结)
[外链图片转存中…(img-C7Subfri-1627094085897)]
[外链图片转存中…(img-Fo09WEZG-1627094085898)]