java多线程面试(二)

news2024/11/18 14:38:11

1.说一下你对java内存模型JVM的理解

java内存模型是一种抽象的模型,被定义出来屏蔽各种硬件和操作系统的访问差异。

  • JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存 (Main Memory)中,每个线程都有
    一个私有的本地内存 (Local Memory),本地内存中存储了该线程以读/写共享变量的副本。

2说说你对原子性,可见性,有序性的理解

  • 原子性是指一个操作不可分割,不可中断,要么全部执行,要么全不执行(synchronized)
  • 可见性:是指一个线程修改了共享变量,其他线程能够立即知道这个修改
  • 有序性:对于一个线程的执行代码,从前往后依次执行,单线程下可以认为是有顺序的,但是并发的时候有肯能会发生指令重排。

3. 什么是指令重排

在执行程序的时候,为了提高性能,编译器和处理器常常会对指令进行重排序。

  • 编译器的优化重排序。编译器在不改变单线程程序的语义下可以重新安排语句的执行顺序。
  • 指令级并行的重排序,如果不存在数据依赖性,处理器可以改变语句对应的机器执行顺序。
  • 内存系统的重新排序,由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行

4.指令重排的限制

指令重排有两个规则:happens-before和as-if-serial来约束
happens-before的定义

  • 如果一个操作在happens-before的另一个操作之前,那么第一个操作的执行结果将对第二个操作可见,而且第一个的操作执行顺序在第二个之前
  • 两个关系存在着happens-before关系,并不意味着java平台的具体实现就必须按照顺序来执行,只要执行结果保持一致,那么重排序不非法。
    happens-before的规则
  • 程序顺序规则
  • 监视器锁过规则: 对于一个锁的解锁,happens-before于随后对这个锁进行加锁
  • volatile变量规则:对一个volatiile域的写,happens-before于任意后续对这个域进行读
  • 传递性:如果a后是b,b后是c,那么a happens-before c
  • start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的 ThreadB.start()操作
    happens-before于线程B中的任意操作。
  • join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作 happens-before于线程A从
    ThreadB.join()操作成功返回。

5.as-if-serial是什么,单线程一定是顺序的吗?

as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),单线程程序的执行结果不能被改变。
编译器、runtime和处理器都必须遵守as-if-serial语义。

6.synchronized使用方式

  1. 修饰实例方法:作用于当前对象获取锁,进入同步代码前要获得当前对象实例的锁
  2. 修饰静态方法:也就是给当前类加锁,会作用于类的所有对象实例,进入同步代码前要获得当前 class 的 锁。
    因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管 new 了多少个对
    象,只有一份)。
    如果一个线程 A 调用一个实例对象的非静态 synchronized 方法,而线程 B 需要调用这个实例对象所属类的静
    态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized方法占用的锁是当前类的锁,
    而访问非静态 synchronized 方法占用的锁是当前实例对象锁。
synchronized void staic method() {
//业务代码
}
  1. 修饰代码块:指定加锁对象,对给定对象/类加锁。 synchronized(this|object) 表示进入同步代码库前要获得
    给定对象的锁。 synchronized(类.class) 表示进入同步代码前要获得 当前 class的锁

7.synchronized的原理

1.synchronized修饰代码块的时候,jvm采用monitorenter和moninorexit指令来实现同步,monitorenter标记开始位置,monitorexit标记结束位置
2.synchronized修饰同步方法,jvm采用ACC_Synchronized标记来实现同步,这个标识指明了该方法是一个同步方法。

synchronized锁住的是什么呢?
monitorenter、monitorexit或者ACC_SYNCHRONIZED都是基于Monitor实现的。

实例对象结构里有对象头,对象头里面有一块结构叫Mark Word,Mark Word指针指向了monitor。
所谓的Monitor其实是一种同步工具,也可以说是一种同步机制。在Java虚拟机(HotSpot)中,Monitor是由
ObjectMonitor实现的,可以叫做内部锁,或者Monitor锁。
ObjectMonitor的工作原理:
ObjectMonitor有两个队列:WaitSet、EntryList,用来保存ObjectWaiter 对象列表。
_owner,获取 Monitor 对象的线程进入 _owner 区时, _count + 1。如果线程调用了wait() 方法,此时会释放
Monitor 对象, _owner 恢复为空, _count - 1。同时该等待线程进入 _WaitSet 中,等待被唤醒。

同步是锁住的什么东西:
monitorenter,在判断拥有同步标识 ACC_SYNCHRONIZED 抢先进入此方法的线程会优先拥有 Monitor 的
owner ,此时计数器+1。
monitorexit,当执行完退出后,计数器-1,归 0 后被其他进入的线程获得。

8.除了原子性,synchronized可见性,有序性,可重入性怎么实现?

可见性:

  • 线程加锁前,将清空工作内存中的值,从而使共享变量需要从主内存中读取最新的值
  • 线程加锁后,其他线程无法获得主内存中的共享变量
  • 线程解锁前,必须把共享变量的最新值刷入到主内存中。

有序性:

  • synchronized同步的代码块,具有排他性,所以synchronized能保证同一时刻代码是单线程执行的。
    实现可重入性:
    synchronized锁对象的时候有个计数器,会记录获取锁的次数,执行完代码就会减去一,清零就会释放锁。

9. 锁升级

锁升级顺序: 无锁-----》 偏向锁 -----》轻量锁 -----》重量级锁

10. synchronized做了哪些优化?

JDK1.6前synchronized是调用monit的enter和exit这种锁被叫做重量级锁,1.6之后就进行优化如增加适应性锁,锁消除,锁粗化,轻量级锁,偏向锁等策略

  • 偏向锁:在无竞争的情况下,只是在Mark Word里存储当前线程指针,CAS操作都不做。
  • 轻量级锁:在没有多线程竞争时,相对重量级锁,减少操作系统互斥量带来的性能消耗。但是,如果存在锁竞争,除了互斥量本身开销,还额外有CAS操作的开销。
  • 自旋锁:减少不必要的CPU上下文切换。在轻量级锁升级为重量级锁时,就使用了自旋加锁的方式
  • 锁粗化:将多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁。
  • 锁消除:虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除

10.说说synchronized和ReentrantLock的区别?

在这里插入图片描述

11.AQS了解多少

AQS就是AbstractQueuedSynchronized抽象同步队列,简称AQS。它是并发包中的基础,并发包中的锁就是基于AQS实现的。

  • AQS是基于一个双向队列,其内部定义了一个节点类node,Node节点内部的SHARED用来标记该线程是获取共享资源时被阻碍挂起后放入AQS队列的,EXCLUSIVE用来标记线程是取独占资源时被挂起后放入AQS队列的。
  • AQS 使用volatile修饰int的成员变量state来表示同步状态。
  • 获取state分为共享式和独占式,一个线程使用独占式获取资源,其他线程就会在获取失败后被阻塞。一个线程使用共享式获取资源,另一个线程还可以使用CAS方式获取资源。
  • 如果共享资源被占用,需要一定的阻塞等待来唤醒机制来保证锁的分配,AQS将会竞争共享资源失败的线程添加到一个变体的CLH中。

12.ReentrantLock实现原理

Reentrantlock是可重入的独占锁,

// 创建非公平锁
ReentrantLock lock = new ReentrantLock();
 // 获取锁操作
lock.lock();
 try {
 // 执行代码逻辑
} catch (Exception ex) {
 // ...
 } finally {
 // 解锁操作
lock.unlock();
 }

new Reentrantlock默认的是创建非公平锁
公平锁:

  • 公平锁是指多个线程按照申请锁的顺序来获取锁
  • 公平锁的优点是等待锁的线程不会饿死,缺点是整体吞吐效率相对非公平锁要低
    非公平锁:
  • 非公平锁是多个线程加锁的时候,直接尝试获取锁,获取不到才会到队尾等待,但如果此时锁刚好可以用,那么这个线程可以无阻碍的直接获取到锁。
  • 非公平锁的优点是可以减少唤醒线程的开销,整体的吞吐效率高,因为线程有几率不阻塞直接获取锁,CPU不必唤醒所有的线程,缺点是处于等待的线程可能会被饿死。

13.Reentrantlock怎么实现公平锁

Reentrantlock默认是非公平锁nonfairSync。

 public ReentrantLock() {
 sync = new NonfairSync();
 }

同时也可以在构造函数中传递参数,实现公平 锁 fairSync

 ReentrantLock lock = new ReentrantLock(true);--- ReentrantLock
 // true 代表公平锁,false 代表非公平锁
public ReentrantLock(boolean fair) {
 sync = fair ? new FairSync() : new NonfairSync();
 }

14.CAS了解多少

CAS 比较并交换 主要是包含三个参数 共享变量A的内存地址,预期值B,和共享变量C的值,只有当内存地址A中的值等于B时候才能更新为新值C。作为一条CPU指令,本身是能保证原子性的。
CAS三大问题:

  1. ABA问题:并发条件下如果A可能在修改中间变为b,b又变为A,此时A非一开始的a,这时去修改数据虽然会成功但是可能会存在问题,解决方案每次修改可以是加版本号
  2. 循环性能开销:自旋CAS如果一直不成功,一直循环,会给CPU带来非常大的开销。解决方案:在java中会设置一个自旋次数,超过一定次数,默认就会停止(默认10次)。
  3. 只能保证一个变量的原子操作:CAS保证的是一个变量执行原子操作,如果对多个变量无法直接保证原子性。解决方法:可以考虑用锁来保证原子的操作性,可以考虑合并多个变量,将多个变量封装到一个对象中。

15.Java有哪些保证原子性的方法?如何保证多线程下i++ 结果正确

  1. 使用原子类,如AtomicInteger,AtomicBoolean(内部是通过CAS实现)
  2. 使用juc中的锁
  3. 使用Synchronized

16.如果避免死锁

死锁是指两个或以上的线程争夺资源而造成的相互等待的现象,在无外力的作用下这些线程会一直等待而无法运行下去。
死锁的四个条件:互斥条件,请求并持有,不可剥夺条件,环路等待
如何避免呢:互斥是必须的,我们可以一次性请求所以数据(互斥条件),针对不可剥夺条件如果我们请求不到其他的资源,始终没有释放,可以将本身的资源进行释放。对于环路等待那么可以按照申请的资源编号来预防。

17 countDownLatch和CyclicBarrier

  1. CountDownLatch同步倒计数器。
  2. CyclicBarrier同步屏障
    (两者可以看我多线程中文章)

18.CyclicBarrier和CountDownLatch有什么区别

在这里插入图片描述

19…Semaphore(信号量)

semaphore(信号量)用来控制同时访问特定资源线程数量。通过协调各个线程以保证合理使用公共资源。它可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接

ps:喜欢请点点关注,你的攒是我前进的动力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL语句详解二-DDL(数据定义语言)

文章目录 操作数据库创建:Create查询:Retrieve修改:Update删除:Delete使用数据库 操作表常见的几种数据类型创建:Create复制表 查询:Retrieve修改:Update删除:Delete 操作数据库 创…

Spring Cloud配置中心

微服务意味着要将单体应用中的业务拆分成一个个子服务 , 每个服务的粒度相对较小 ,因此系统中会出现大量的服务。 由于每个服务都需要必要的配置信息才能运行 , 所以一套集中式的 , 动态的配置管理设施是必不可少的。 Spring Cloud 提供了 ConfigServer 来解决这个问题 . Sp…

客户端请求服务器的步骤

当我们在浏览器地址栏输入’http://www.xxx.com/api/xxx"时,客户端是如何找到服务器并发送请求的? 1.先找到服务器 a.检测浏览器缓存有没有缓存该域名对应的IP地址,有则通过IP地址取找服务器。 b.检测本地的hosts文件,是否有…

ROS2——launcher

在ROS2中,launcher 文件是通过Python构建的,它们的功能是声明用哪些选项或参数来执行哪些程序,可以通过 launcher 文件快速同时启动多个节点。一个 launcher 文件内可以引用另一个 launcher 文件。 使用 launcher 文件 ros2 launch 可以代替…

STM32 SPI通信协议3——读取MAX6675温度传感器

在上两章中,我们已经配置了相应的GPIO和SPI功能。这里说一下MAX6675如何读取温度。 从MAX6675手册中我们可以看到,当0的时候SCK启动,数据线开始发送信息,此时可以读取数据,当数据读完后,再拉高电平停止发送…

VMware Workstation17安装教程及安装Ubuntu22.04系统

编程如画,我是panda! 前言 VMware Workstation Pro 是一款高级虚拟化软件,使用户能够在单一计算机上同时运行多个操作系统,如Windows、Linux和macOS,而无需重新启动。具备虚拟机快照、高级网络配置、克隆和复制功能&a…

Redis-浅谈redis.conf配置文件

Redis.conf Redis.conf是Redis的配置文件,它包含了一系列用于配置Redis服务器行为和功能的选项。 以下是Redis.conf中常见的一些选项配置: bind: 指定Redis服务器监听的IP地址,默认为127.0.0.1,表示只能本地访问,可以…

大数据毕业设计:房屋数据分析可视化系统 预测算法 可视化 商品房数据 Flask框架(源码+讲解视频)✅

毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏) 毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总 🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题&#xff…

网卡高级设置-提高网络环境

网卡高级设置,提高网络质量排除一些连接问题 一、有线网卡 1、关闭IPv6; 可以关闭协议版本6,因为它会引起一些网络连接问题,而且现在几乎用不到IP6。 2、关闭节约电源模式; 右击计算机->设备->设备管理器-&…

Unity游戏开发面试知识点全解读

Unity游戏开发面试知识点全解读 在数字化世界中,Unity游戏开发不仅是一种艺术形式和商业活动,而且已成为推动整个数字娱乐产业创新和进步的重要力量。Unity以其易用性、高效性和灵活性,赢得了全球开发者的青睐,从独立开发者到大型…

MySQL题目示例

文章目录 1.题目示例 1.题目示例 09)查询学过「张三」老师授课的同学的信息 SELECT s.*, c.cname, t.tname, sc.score FROM t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc WHERE t.tid c.tid AND c.cid sc.cid AND sc.sid s.sid …

07- OpenCV:模糊图像

目录 一、模糊原理 二、模糊的相关处理方法: 1、均值滤波(归一化盒子滤波) 2、高斯滤波(正态分布的形状) 3、中值模糊 4、双边模糊算法(美容软件) 5、相关代码: 6、几种模糊算法的比…

【问题记录】数据处理部分正常部分异常

一,问题现象 正常处理效果为压缩到-12db,一部分压缩效果正确,一部分数据处理效果不正确。准确来说,只有1/4的数据处理正确。 二,问题原因 传入process的size不正确,导致读出来4096个字节,但…

SQLyog软件安装(保姆级别)

SQLyog 安装配置使用 首先下载SQLyog 软件,并解压 选择自己操作系统的版本 双击点击 .exe 文件,进行安装 选择安装语言,默认中文,直接点击【OK】即可 点击【下一步】 先【勾选】同意协议,再点击【下一步】 …

Windows项目部署

目录 一.安装jdk 1.1 安装 1.2 配置 二.安装Tomcat 2.1 安装 2.2 配置防火墙 三. 安装MySQL 3.1 安装 2.2 内部连接 3.3 外部连接 四. 部署项目 4.1 项目部署 4.2 修改mysql的用户密码 一.安装jdk 1.1 安装 选择jdk安装包双击进行傻瓜式安装即可,这里注意记住安…

Gogs - 管理协作者

Gogs - 管理协作者 References 仓库设置 管理协作者 权限设置 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【目标检测】Anchor-based模型:基于K-means算法获取自制数据集的Anchor(yolo源码)

在Anchor-based目标检测模型中,根据数据集选择合适的Anchor有利于加快模型的收敛速度以及减少模型的边框预测误差。本篇文章首先介绍Anchor在目标检测模型中的作用;然后介绍K-means聚类算法;最后介绍yolo源码中自制数据集的Anchor的获取方法。…

企业如何做到安全又极速的分发传输大文件

在当代企业运营中,文件的传输和分发是至关重要的任务。然而,随着文件体积的增大和信息敏感性的凸显,企业需要找到一种既安全又能够高效传输大文件的方法。本文将深入探讨如何在企业环境中实现安全又高效的大文件传输。 一、分发大文件时需要注…

.NET core 中的Kestrel 服务器

什么是Kestrel? Kestrel 是一个跨平台的Web服务器,会默认在ASP.NET Core 项目模板中对其进行配置。未使用 IIS 托管时,ASP.NET Core 项目模板默认使用 Kestrel。 Kestrel 的功能包括: 跨平台:Kestrel 是可在 Window…

spring boot mybatis-plus dynamic-datasource 配置文件 相关依赖环境配置

spring boot mybatis-plus dynamic-datasource 配置文件 相关依赖环境配置 ##yaml配置 server:port: 8866servlet:context-path: /yymtomcat:max-threads: 300connection-timeout: 57000max-connections: 500connection-timeout: 57000 spring:datasource:dynamic:primary: m…