3.9多线程
创始人
2024-05-31 23:06:03

一.常见锁策略

1.悲观锁 vs乐观锁

体现在处理锁冲突的态度

①悲观锁:预期锁冲突的概率高

所以做的工作更多,付出的成本更多,更低效

②乐观锁:预期锁冲突的概率低

所以做的工作少,付出的成本更低,更搞笑

2.读写锁 vs 普通的互斥锁

①普通的互斥锁,只有两个操作 加锁和解锁

只有两个线程针对同一个对象加锁,就会产生互斥

②读写锁:有三个操作

针对读锁和读锁之间,是不存在互斥的关系--->因为多线程同时读一个变量,不会有线程安全的问题

读锁和写锁之间,写锁和写锁才需要互斥

而且很多场景中,都是读多写少

3.重量级锁 vs 轻量级锁

是为了处理锁冲突的结果

重量级锁 做了更多的事情,开销大,轻量级锁反之亦然

大多数情况下,悲观锁一般都是重量级锁,乐观锁一般都是轻量级锁

比如: 在使用的锁中,如果锁是基于内核的一些功能来实现的(比如调用了操作系统提供的mutex接口).一般认为这是重量级锁

如果锁是纯纯用户态实现的,一般认为这是轻量级锁,因为用户态的代码更可靠,也更高效

4.挂起等待锁 vs 自旋锁

①挂起等待锁:通过内核的一些机制来实现的.往往比较中 [重量级锁的一种典型实现]

②自旋锁 : 往往是通过用户态代码来实现的,往往比较轻,[轻量级锁的一种典型实现]\

5.公平锁 vs 非公平锁

公平锁:多个线程在等待一把锁的时候谁是先来的,谁就能先获取到这个锁(遵守先来后到

非公平锁:多个线程在等待一把锁的时候不遵守先来后到,每个等待的线程获取到锁的概率是均等的

对于操作系统来说->线程之间的调度是随机的(机会是均等的) .操作系统提供的mutex这个锁.就是属于非公平锁

6.可重入锁 vs 不可重入锁

可以嵌套加锁,就是可重入锁,会死锁的就是不可重入锁

7.synchronized(面试

1)即是一个乐观锁.也是一个悲观锁(根据锁竞争的激烈程度,自适应)

2)不是读写锁,只是一个普通互斥锁

3)既是一个轻量级锁,也是一个重量级锁,(根据锁竞争的激烈程度,自适应)

4)非公平锁 5)可重入锁

二.CAS

compare(比较) and swap(交换)

1.定义

CAS锁:拿着寄存器或者/某个内存的值和另外一个内存的值进行比较,如果值相同了,就交换

伪代码

CAS:提供一个单纯的CAS指令,通过这一条指令,就完成上述伪代码描述的过程

CAS指令:如果上述伪代码的过程只用一条做完,就是原子性,这个时候就是线程安全了

2.作用

1)基于CAS能够实现原子类

(java标准库里提供了一组原子性,针对常用的int.long,,int[]进行了封装,基于cas方式修改,并且线程安全

这段代码是不存线程安全的问题

基于CAS实现的++操作

因为这里既能保证线程安全,又能比synchronized高效

synchronized会涉及到锁的竞争,又要涉及线程的阻塞等待

这里的oldvalue变量,实际实际上可能使用一个寄存器来存的

这个赋值操作就相当于把数据从内存读到寄存器中(load

判定一下当前内存的值是不是和刚刚寄存器取到的值一直

如果判定成功,那就把value设为oldvalue+1.并返回true 循环结束

如果判定失败,继续下次循环,返回true;下次循环还是要先读一下value

这两行代码之间,很有可能有其他线程修改了value的值

为什么上述++操作线程安全

load

cas

2).基于CAS实现自旋锁

自旋锁是一个轻量级锁,也可以视为一个乐观锁

这把锁虽然没能够立即拿到,预期很快就能拿到(假设锁冲突不激烈)

3.ABA问题

1)定义

CAS中的关键就是先比较再交换

比较其实在比较当前值和旧值是否相同

把这两个值相同,就视为中间没有发生改变

但是这句话有漏洞,可能当前值和旧值相同的情况是因为变了然后又变回来了, 这就是ABA

2.案例

举例:ABA产生的BUG

假设小红账户余额 100 他想要取50

当按下取钱操作的时候,机器卡了一下,小红一紧张多按了一下取款

这就相当于 一次取钱操作 执行了两遍 (两个线程,并发的去执行这个取钱操作)

预期是只能取成功一次

如果基于CAS来实现的话

本来应该没问题

第二个线程再比较的时候就会发现,读到的100和原本的50不一样,就会不操作了

但是在取款的一瞬间,小红额度朋友给他转账了50.这个时候就会触发的ABA问题

这个时候第二个线程就会发现还是100.于是又扣了50

3)解决方法

引入版本号

这个版本号只能变大,修改变量的时候,比较的不是变量而是比较版本号

当引入版本号以后,t2再次尝试进行这里的比较版本操作

就会发现版本的旧值和当前的值并不匹配,就直接放弃修改

或者加入时间戳

看当前读到的内存改变的时间戳有没有变化

相关内容

热门资讯

高... 作为一个人,我天生就有沟通的能力。 我想结交新朋友。 我最近尝试使用了几个约会应用程序,所以今天我将...
A... 在现代科技飞速发展的时代,人工智能(AI)已经渗透到我们日常生活的方方面面。 人工智能的应用范围十分...
管... 如何创建关家坡服装版基本信息、关家坡服装版使用教程随着技术的不断发展管家婆仓库管理软件教程,管家婆软...
C... CAD操作不熟练?数百款CAD插件附带视频教程。 不要再说您不会使用 CAD。如今,工程项目中使用C...
中... 写下前面的话:作为管理员之一section软件教程交流群,这里简单宣传一下GMT。 目前有两个群账号...