热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java同步锁试题_2020秋招最新面试题:并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)...

对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能

对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的内功。

那到底应该怎么学习并发编程呢? Java SDK的并发工具包有很多,是要死记硬背每-一个工 具的优缺点和使用场景吗?当然不是,想要学好并发编程,你需要从一个个单一的知识和技术中“跳出来”,高屋建瓴地看问题,并逐步建立自己的知识体系。

可 重 入 锁 ReentrantLock 及 其 他 显 式 锁 相 关 问 题

问题一: 跟Synchronized相比, 可重入锁Reentrant Lock其实现原理有什么不同?

其实, 锁的实现原理基本是为了达到一个目的: 让所有的线程都能看到某种标记。Synchronized 通 过 在 对 象头 中 设 置 标 记 实 现 了这 一 目 的 , 是 一 种 JVM 原生的锁实现方式, 而 Reentrant Lock 以及所有的基于 Lock 接口的实现类, 都是通 过用一个 volitile 修饰的 int 型变量, 并保证每个线程 都 能拥 有 对 该 int 的可见性和原子修改, 其本质是基于所谓的 AQS 框架。

问题二: 那么请谈谈 AQS 框架是怎么回事儿?

AQS( Abstract Queued Synchronizer 类 ) 是 一 个 用 来 构 建 锁 和 同 步 器的框架, 各种Lock包中的锁( 常用的有Reentrant Lock、ReadWrite Lock) , 以及其他如 Semaphore、 Count Down Latch, 甚至 是 早期的 Future Task 等, 都是基于 AQS 来 构建 。

1. AQS 在 内 部 定 义 了 一 个 volatile int state 变 量 , 表 示 同 步 状 态 : 当 线程调用 lock 方法时 , 如果 state= 0 , 说明没有任何线程占有共享资源的锁, 可以获得锁并将 state= 1 ; 如果 state= 1 , 则说明有线程目前正在使用共享变量, 其他线程必须加入同步队列进行等待。

2. AQS 通 过 Node 内 部 类 构 成 的 一 个 双 向 链 表 结 构 的 同 步 队 列,来完成线程获取锁的排队工作, 当有线程获取锁失败后, 就被添加到队列末尾。Node 类 是 对 要 访 问 同 步 代 码 的 线 程 的 封 装 , 包 含 了 线 程 本 身 及 其 状 态 叫wait Status( 有五种不同 取值, 分别表示是否被阻塞, 是否等待唤醒, 是否 已 经 被 取 消 等 ) , 每个 Node 结点关联其prev 结点和next 结 点,方便线程释放锁后快速唤醒下一个在等待的线程, 是一个 FIFO 的过程。

Node 类 有 两 个 常 量 , SHARED 和 EXCLUSIVE, 分 别 代 表 共 享 模 式 和 独占 模 式 。 所 谓 共 享 模 式 是 一 个 锁 允 许 多 条 线 程 同 时 操 作 ( 信 号 量Semaphore 就 是 基 于 AQS的 共 享 模 式 实 现 的 ) , 独 占 模 式 是 同 一 个 时间 段 只 能 有 一 个 线 程 对 共 享 资 源 进 行 操 作 , 多 余 的 请 求 线 程 需 要 排 队 等 待( 如 Reentran Lock) 。

3. AQS

通 过 内 部 类Condition Object构 建 等 待 队 列 ( 可 有 多 个 ) , 当Condition调 用wait()方 法 后 , 线 程 将 会 加 入 等 待 队 列 中 , 而 当Condition 调 用 signal() 方 法 后 , 线 程 将 从 等 待 队 列 转 移 动 同 步 队 列 中进 行 锁 竞 争 。

4. AQS

和Condition各 自 维 护 了 不 同 的 队 列 , 在 使 用Lock和Condition 的时候, 其实就是两个队列的互相移动。

问题三: 请尽可能详尽地对比下Synchronized和Reentrant Lock的异同。

Reentrant Lock 是 Lock 的实现类, 是一个互斥的同步锁。

从 功 能 角 度 , Reentrant Lock比Synchronized的 同 步 操 作 更 精 细( 因 为 可 以 像 普 通 对 象 一 样 使 用 ) , 甚 至 实 现Synchronized没 有 的高 级 功 能 , 如 :等待可中断: 当持有锁的线程长期不释放锁的时候, 正在等待的线程可以选择放 弃等待, 对处理 执行时间 非常长的 同步块很 有用。

带超时的获取锁尝试: 在指定的时间范围内获取锁, 如果时间到了仍然无法 获 取 则 返 回 。

可 以 判 断 是 否 有 线 程 在 排 队 等 待 获 取 锁 。

可 以 响 应 中 断 请 求 : 与Synchronized不 同 , 当 获 取 到 锁 的 线 程 被 中断 时 , 能 够 响 应 中 断 , 中 断 异 常 将 会 被 抛 出 , 同 时 锁 会 被 释 放 。

可 以 实 现 公 平 锁 。

从锁释放角度, Synchronized 在 JVM 层面上实现的, 不但可以通过一些监控工具监控 Synchronized 的锁定, 而且在代码执行出现异常时, JVM 会自动释放锁定;但是使用 Lock 则不行, Lock 是通过代码实现的, 要保证锁定一定会被释放, 就必须将 un Lock() 放到f inally{} 中。

从 性 能 角 度 , Synchronized早 期 实 现 比 较 低 效 , 对 比Reentrant Lock, 大多数场景性能都相差较大。但 是 在 Java 6 中 对 其 进 行 了 非 常 多 的 改 进 , 在竞争不激烈时 ,

Synchronized 的 性 能 要 优 于 Reetrant Lock ; 在 高 竞 争 情 况 下 ,Synchronized 的性 能会下降 几十倍, 但是 Reetrant Lock 的 性 能 能 维 持常态。

问题四: Reentrant Lock 是如何实现可重入性的?

Reentrant Lock 内 部 自 定 义 了 同 步 器 Sync( Sync 既实现了 AQS, 又实现了 AOS, 而 AOS提 供 了 一 种 互 斥 锁 持 有 的 方 式 ) , 其实就是加锁的 时 候 通 过 CAS 算法, 将线程对象放到一个双向链表中, 每次获取 锁 的时 候 , 看 下 当 前 维 护 的 那 个 线 程 ID 和 当 前 请 求 的 线 程 ID 是 否一 样 ,一样就可重入了。问题五: 除了 Reetrant Lock, 你还接触过 JUC 中的哪些并发工具?

问题六: 请谈谈 Read Write Lock 和 Stamped Lock。

问题七: 如何让 Java 的线程彼此同步? 你了解过哪些同步器? 请分别介绍下。

问题八: Cyclic Barrier和Count Down Latch 看起来很相似, 请对比下呢?

Java 线程池相关问题

问题一: Java 中的线程池是如何实现的?

 在 Java 中 , 所 谓 的 线 程 池 中 的 “ 线 程 ” , 其 实 是 被 抽 象 为 了 一 个 静 态内 部 类Worker, 它 基 于AQS实 现 , 存 放 在 线 程 池 的Hash Set workers 成 员 变 量 中 ;

 而 需 要 执 行 的 任 务 则 存 放 在 成 员 变 量work Queue( Blocking Queue work Queue) 中。这 样 , 整 个 线 程 池 实 现 的 基 本 思 想 就 是 : 从work Queue中 不 断 取 出需 要 执 行 的 任 务 , 放 在 Workers 中 进 行 处 理 。

问题二: 创建线程池的几个核心构造参数?

Java中 的 线 程 池 的 创 建 其 实 非 常 灵 活 , 我 们 可 以 通 过 配 置 不 同 的 参数, 创建出行为不同的线程池, 这几个参数包括: core Pool Size: 线程池的核心线程数。maximum Pool Size: 线程池允许的最大线程数。

keep Alive Time: 超过核 心线程数 时闲置线 程的存活 时间。

work Queue: 任 务 执 行 前 保 存 任 务 的 队 列 , 保 存 由 execute 方 法 提 交的 Runnable 任 务 。

问题三: 线程池中的线程是怎么创建的? 是一开始就随着线程池的启动创建好的吗?

显 然 不 是 的 。 线 程 池 默 认 初 始 化 后 不 启 动Worker, 等 待 有 请 求 时 才 启动 。每 当 我 们 调 用execute()方 法 添 加 一 个 任 务 时 , 线 程 池 会 做 如 下 判断 :

 如 果 正 在 运 行 的 线 程 数 量 小 于core Pool Size, 那 么 马 上 创 建 线 程 运 行这 个 任 务 ;

 如 果 正 在 运 行 的 线 程 数 量 大 于 或 等 于core Pool Size, 那 么 将 这 个 任 务放 入 队 列 ;

 如果这 时候队列 满了, 而且正 在运行的 线程数量 小于maximum Pool Size, 那么还 是要创建 非核心线 程立刻运 行这个任 务;

 如果队 列满了, 而且正 在运行的 线程数量 大于或等 于maximum Pool Size, 那么线程池会抛出异常Reject Execution Exception。当 一 个 线 程 完 成 任 务 时 , 它 会 从 队 列 中 取 下 一 个 任 务 来 执 行 。当 一 个线 程 无 事 可 做 , 超 过 一 定 的 时 间 ( keep Alive Time) 时 , 线 程 池 会断。

如 果 当 前 运 行 的 线 程 数 大 于core Pool Size, 那么 这个线 程就 被停掉 。所以线程池的所有任务完成后, 它最终会收缩到core Pool Size的大小。问题四: 既然提到可以通过配置不同参数创建出不同的线程池, 那么Java 中默认实现好的线程池又有哪些呢? 请比较它们的异同。

问题五: 如何在 Java 线程池中提交线程?

…………………………

Java 内存模型相关问题

问题一: 什么是 Java 的内存模型, Java中各个线程是怎么彼此看到对方的变量的?

Java 的内存模型定义了程序中各个变量的访问规则, 即在虚拟机中将变量存储到内存和从内存中取出这样的底层细节。

此处的变量包括实例字段、 静态字段和构成数组对象的元素, 但是不包括局部变量和方法参数, 因为这些是线程私有的, 不会被共享, 所以不存在竞争问题。

Java 中各个线程是怎么彼此看到对方的变量的呢? Java 中定义了主内存与工作内存的概念:

所有的变量都存储在主内存, 每条线程还有自己的工作内存, 保存了被该线程使用到的变量的主内存副本拷贝。线程对变量的所有操作( 读取、 赋值) 都必须在工作内存中进行, 不能直接读写主内存的变量。 不同的线程之间也无法直接访问对方工作内存的变量, 线程间变量值的传递需要通过主存。问题二: 请谈谈 volatile 有什么特点, 为什么它能保证变量对所有线程的可见性?

问题三: 既然 volatile 能够保证线程间的变量可见性, 是不是就意味着基于volatile 变量的运算就是并发安全的?

问题四: 请对比下 volatile 对比 Synchronized 的异同。

问题五: 请谈谈 Thread Local 是怎么解决并发安全的?

问题六: 很多人都说要慎用 Thread Local, 谈谈你的理解, 使用Thread Local 需要注意些什么?

……………………

Synchronized 相关问题问题一: Synchronized 用过吗, 其原理是什么?

问题二: 你刚才提到获取对象的锁, 这个“ 锁” 到底是什么? 如何确定对象的锁?

问题三: 什么是可重入性, 为什么说 Synchronized 是可重入锁? 可 重 入 性

问题四: JVM 对 Java 的原生锁做了哪些优化?

问题五: 为什么说 Synchronized 是非公平锁?

问题六: 什么是锁消除和锁粗化?

问题七: 为什么说Synchronized是一个悲观锁? 乐观锁的实现原理又是什么? 什么是CAS, 它有什么特性?

问题八: 乐观锁一定就是好的吗?

其他问题JAVA 并发知识库

JAVA 线程实现/创建方式

4 种线程池

线程生命周期(状态)

终止线程 4 种方式

sleep 与 wait 区别

start 与 run 区别

JAVA 后台线程

JAVA 锁

线程基本方法

线程上下文切换

同步锁与死锁

线程池原理

JAVA 阻塞队列原理

CyclicBarrier、CountDownLatch、Semaphore 的用法

volatile 关键字的作用(变量可见性、禁止重排序)

如何在两个线程之间共享数据

ThreadLocal 作用(线程本地存储)

synchronized 和 ReentrantLock 的区别

ConcurrentHashMap 并发

Java 中用到的线程调度

进程调度算法

什么是 CAS(比较并交换-乐观锁机制-锁自旋)

什么是 AQS(抽象的队列同步器)

所有的并发编程面试题已合成文档,由于篇幅过长,没办法全部上传,需要完整压缩文档的伙伴可以“加我VX小助理来免费获取到*(看UP主主页哦)”

资料展示

5b022e13f5f80dc7b158d1d9c4752725.png

b627cf859eeb261f46581702dbc9212d.png

知识脑图:48e812111c2b32f257dc3206aec3e410.png

忍不住想吐槽,知识点多且复杂。。。。。。。。。ca3697e966bdb75d78a5e9f71b3f259e.png



推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有