【Java之多线程】一文帮你彻底搞懂多线程面试重难点,dubbo和zookeeper面试

二. 读写锁

===================================================================

1. 理解


在这里插入图片描述

我们都知道,当我们通过多线程方式尝试修改同一数据时,一般都可能引发线程安全问题,但当我们通过多线程方式尝试读取同一数据时,一般不会引发线程安全问题,因此,我们可以根据读和写的不同场景来给读和写操作分别加上不同的锁。

Java当中的synchronized不会对读和写进行区分,默认使用后线程都是互斥的

2. 用法


以Java为例,在标准库中存在这样一个类ReentrantReadWriteLock

源代码如下

public class ReentrantReadWriteLock

implements ReadWriteLock, java.io.Serializable {

private static final long serialVersionUID = -6992448646407690164L;

/** Inner class providing readlock */

private final ReentrantReadWriteLock.ReadLock readerLock;

/** Inner class providing writelock */

private final ReentrantReadWriteLock.WriteLock writerLock;

/** Performs all synchronization mechanics */

final Sync sync;

/**

  • Creates a new {@code ReentrantReadWriteLock} with

  • default (nonfair) ordering properties.

*/

public ReentrantReadWriteLock() {

this(false);

}

该类中提供了两个方法:

public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }

此方法可以创建出一个读锁实例

public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }

此方法可以创建出一个写锁实例

某个线程被读锁修饰后,这两个线程之间不会互斥,而是完全同时并发执行,一般将读锁用于线程读取数据比较多的场景;而当某个线程被写锁修饰后,这两个线程会互斥,一个线程会执行,而另一个线程会阻塞等待,因此必须是一个线程执行完了,另一个线程才会执行,一般用于修改数据比较多的场景

三. 重量级锁和轻量级锁

=========================================================================

1. 原理


锁的核心特性 “原子性”,这样的机制追根溯源是 CPU 这样的硬件设备提供的

1.CPU 提供了 “原子操作指令”。

2. 操作系统基于 CPU 的原子指令,实现了 mutex 互斥锁.

3. JVM 基于操作系统提供的互斥锁。实现了 synchronized 和 ReentrantLock 等关键字和类。

在这里插入图片描述

注意:synchronized 并不仅仅是对 mutex 进行封装, 在 synchronized 内部还做了很多其他的工作

2. 理解


1.重量级锁依赖了OS提供的mutex,的开销一般很大,往往是通过内核来完成的

2.轻量级加锁一般不使用mutex,开销一般比较小,一般通过用户态就能直接完成

2. 区分用户态和内核态


我们可以类比一个生活中的例子,当去银行办理业务时,如果是通过用户在银行工作人员的指导下自己在窗口外完成,那么效率会比较高,就像计算机中的用户态一样。而当我们把自己的业务交给银行相关人员去完成时,由于银行工作人员的闲忙时间是不可控的,因此无法保证效率,就好比计算机中的内核态。

四. 自旋锁

===================================================================

1. 理解


当两个线程为了完成任务同时竞争一把锁时, 拿到锁的那个线程会立马执行任务,而没拿到就会阻塞等待,当一个线程把锁释放后,另一个线程不会被立即唤醒,而是等操作系统将其进行一系列的调度到CPU中的操作才能被唤醒然后执行任务,这种锁叫做挂起等待锁,线程在抢锁失败后进入阻塞状态,放弃 CPU,需要过很久才能再次被调度。但实际上,大部分情况下,虽然当前抢锁失败,但过不了很久,锁就会被释放,所以没必要就放弃 CPU。这个时候就可以使用自旋锁来处理这样的问题。

2. 实现方式


自旋锁的伪代码为:while (抢锁(lock) == 失败) {}

如果获取锁失败,就会立即再尝试获取锁,无限循环,直到获取到锁为止。第一次获取锁失败, 第二次的尝试会在非常短的时间内到来,一旦锁被其他线程释放, 就能第一时间获取到锁

3. 优缺点


自旋锁是一种典型的轻量级锁的实现方式,它没有放弃 CPU, 不涉及线程阻塞和调度,一旦锁被释放,就能第一时间获取到锁,这样会大大提高代码的执行效率,但如果锁被其他线程持有的时间比较久, 那么就会持续地消耗 CPU 资源。(而挂起等待的时候是不消耗 CPU 的)

因此,我们应该注意自旋锁的适用场合:

  1. 如果多个线程执行任务时锁的冲突比较低,或者线程持有锁的时间比较短,此时使用自旋锁比较合适

  2. 如果某个线程任务对CPU比较敏感,且不希望吃太多CPU资源,那么此时就不太适合使用自旋锁。

注意:synchronized自身已经设置好了自旋锁和挂起等待锁,会根据不同的情况自动选择最优的使用方案

五. 公平锁和非公平锁

========================================================================

1. 理解


若有三个线程 A,B,C。

A先尝试获取锁,获取成功了,因为只有一把锁,所以B和C线程都会阻塞等待,那么如果A用完了锁后,B和C线程哪一个会最先获取到锁呢?

  1. 公平锁:遵守先来后到原则,因为B线程比C线程来的早一点,所以B线程先获取到锁

  2. 非公平锁:没有先来后到原则,B和C线程获取到锁的概率是随机的

2. 注意事项


操作系统内部的线程调度就可以视为是随机的,如果不做任何额外的限制,锁就是非公平锁。如果要想实现公平锁,就需要依赖额外的数据结构(比如队列) 来记录线程们的先后顺序。公平锁和非公平锁没有好坏之分, 关键还是看适用场景(大部分情况下非公平锁就够用了,但当我们希望线程的调度时间成本是可控的,那么此时就需要用到公平锁了)

注意:synchronized为非公平锁

六. 可重入锁和不可重入锁

==========================================================================

1. 为什么要引入这两把锁


(1)实例一

在介绍可重入锁和不可重入锁之前,大家先来思考一个问题,为什么Java中的main函数要用static来修饰?

public class Test {

public static void main(String[] args) {

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024b 备注Java获取(资料价值较高,非无偿)
img

总结

阿里伤透我心,疯狂复习刷题,终于喜提offer 哈哈~好啦,不闲扯了

image

1、JAVA面试核心知识整理(PDF):包含JVMJAVA集合JAVA多线程并发,JAVA基础,Spring原理微服务,Netty与RPC,网络,日志,ZookeeperKafkaRabbitMQ,Hbase,MongoDB,Cassandra,设计模式负载均衡数据库一致性哈希JAVA算法数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算共30个章节。

image

2、Redis学习笔记及学习思维脑图

image

3、数据面试必备20题+数据库性能优化的21个最佳实践

image
base,MongoDB,Cassandra,设计模式负载均衡数据库一致性哈希JAVA算法数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算共30个章节。

[外链图片转存中…(img-EfklPJsA-1711593539169)]

2、Redis学习笔记及学习思维脑图

[外链图片转存中…(img-vHJBZsvm-1711593539169)]

3、数据面试必备20题+数据库性能优化的21个最佳实践

[外链图片转存中…(img-u8dsbEq5-1711593539170)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值