java 变量锁_并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)

3ab1a6a4e4879f74e3dbd7cbe64ce506.png

对于一个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< Worker> workers 成 员 变 量 中 ;
 而 需 要 执 行 的 任 务 则 存 放 在 成 员 变 量work Queue( Blocking Queue< Runnable> 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(抽象的队列同步器)
所有的并发编程面试题已合成文档,由于篇幅过长,没办法全部上传资料展示

d0ab75fe3d79ec5a4f5b74efb8296986.png

61b0c3ff9d5d7679c80ea069ce1e9cf0.png

知识脑图:

e3d60829fa1001c368af51a4268963e7.png

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

09e4ea163100dca344f28bf1a2ad2c2e.png


快来,一起学习,加入头大家族吧!!

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

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

相关文章

移动端安全 - 安卓Android - 漏洞修复方案整理

敏感数据泄露 明文传输用户名、密码和验证码等敏感信息 MD5/Base64弱加密传输手机、密码等敏感信息 敏感信息在本地加密存储 后台服务器地址泄露。 边信道信息泄漏 在日志中对于密码等敏感信息进行加密存储。 关闭调试接口&#xff0c;禁止输出敏感信息。 未经用户确认调用敏感…

[html] html中如何使用svg?

[html] html中如何使用svg&#xff1f; 1-使用embed标签 推荐优点主流浏览器都支持允许使用脚本缺点不推荐在HTML4和XHTML中使用语法<embed src"svg File Path" type"image/svgxml" width"width" height"height" pluginspage&quo…

element中select默认选中第一个_探索在网页中使用“标注”

github地址&#xff1a;https://github.com/1314mxc/yunUI &#xff0c;欢迎star&#xff01;说起“标注”&#xff0c;在HTML5之前&#xff0c;你可能想起的是各种浏览器插件&#xff0c;emmmmmmm或者说你根本不认为浏览器上可以有这种玩意。但是HTML5来了&#xff0c;这是它的…

ckeditor 框架分析 几个核心“人物”

ckeditor代码中有几个核心的内容&#xff1a; 1. (function(){})(); 2. prototype new 配合&#xff0c;继承属性方法 3. a.event.implementOn() 公共属性扩充 4. e.extend / a.tools.extend 自由扩充 5. a.on 6. j.add 1.(function(){})(); (function(){ //要运行的程序 })();…

项目管理沙龙第五次聚会

项目管理沙龙第五次聚会本次的话题从第30个项目百态模式《短铅笔》开始。“短铅笔”模式里最让人印象深刻的是这一句话“只有把用短的铅笔交上去&#xff0c;才能更换一支长铅笔”。很多人都遇过这样的公司&#xff0c;因为要所谓的“控制成本”&#xff0c;结果却把自己的员工…

算法之排序算法-选择排序与优化

package com.ebiz.sort;import java.text.SimpleDateFormat; import java.util.Date;/*** author YHj* create 2019-07-28 20:58* 选择排序*/ public class Choose {public static void main(String[] args) {int[] arr new int[80000];for (int i 0; i < 80000; i) {arr[…

python 享元模式_python 设计模式之享元(Flyweight)模式

#写在前面这个设计模式理解起来很容易。百度百科上说的有点绕口。#享元模式的定义运用共享技术来有効地支持大量细粒度对象的复用。它通过共享已经存在的对橡大幅度减少需要创建的对象数量、避免大量相似类的开销&#xff0c;从而提高系统资源的利用率。#优点相同对象只要保存一…

[html] 怎样在<pre>标签内不转义<和>符号(原样输出html标签)?

[html] 怎样在标签内不转义<和>符号&#xff08;原样输出html标签&#xff09;&#xff1f; 将HTML代码嵌入到<script typetext/html styledisplay:block>中<script type"text/html" style"display: block;">哈哈哈dfdfd</script>…

单列模式

最近在学设计模式&#xff0c;学到创建型模式的时候&#xff0c;碰到单例模式&#xff08;或叫单件模式&#xff09;&#xff0c;现在整理一下笔记。 在《Design Patterns&#xff1a;Elements of Resuable Object-Oriented Software》中的定义是&#xff1a;Ensure a class on…

算法之排序算法-直接插入排序

package com.ebiz.sort;import java.text.SimpleDateFormat; import java.util.Date;/*** author YHj* create 2019-07-29 8:56* 插入排序*/ public class Insert {public static void main(String[] args) {// int [] arr{101,34,119,1};int[] arr new int[80000];for (int i…

佳能g3800故障灯说明书_热水器维修电话|史密斯燃气热水器出现16故障码

热水器出现故障代码其实是一件很常见的事情&#xff0c;大多是住户的热水器都出现过这样的问题&#xff0c;为了防止这样的事情也发生在我身上&#xff0c;我熟读热水器说明书&#xff0c;终于参透其中的道理&#xff0c;那么接下来我为大家介绍史密斯燃气热水器出现16故障码。…

DrawImage内存不足问题

出现这种问题&#xff0c;分析如下&#xff1a; 1.图片太大&#xff0c;绘制完没有及时释放。所谓图片太大&#xff0c;一种是原始图片本身很大&#xff0c;一种是把小图片拉伸到很大的矩形区域显示。 2.图片格式不对或者参数不对。 3.图片不完整。比如图片只下载了一半&#x…

算法之排序算法-shell排序(交换法)

可以先看注释掉的分析,最后在看三层for循环 package com.ebiz.sort;import java.util.Arrays;/*** author YHj* create 2019-07-30 8:53* shell排序-交换法*/ public class Shell{public static void main(String[] args) {int [] arr{8,9,1,7,2,3,5,4,6};getResult(arr);// Sy…

git语言包安装_Git分布式版本管理系统快速入门指南

为什么要使用版本管理系统无论有没有使用过专业化工具&#xff0c;每个人都或多或少地有版本管理的需求。我们在做论文、写报告或者设计方案时&#xff0c;因为难以避免的不断改动&#xff0c;总会形成很多个不同的版本&#xff0c;我们可能会用“某某设计方案_20180910”这样加…

[html] 如何放大点击的区域?

[html] 如何放大点击的区域&#xff1f; <div class"button">点我</div><style>.button{position:relative;}.button::after{content:"";position:absolute;top:-10px;left:-10px;right:-10px;bottom:-10px;}</style>个人简介 我…

(十)、java内部类与内部类的闭包和回调

一、成员内部类 1.可以把一个内部类看做是一个成员。成员内部类可以无条件访问外部类的所有成员属性和成员方法。 class OutterClass {//外部类private int in 0;static int inn4;public OutterClass(int in) {this.in in;}class InnerClass { //内部类public void outpu…

vb.net中滚动条一直显示没有数据时也显示_Android Studio 中 System Trace 的新增功能...

Android Studio 中 System Trace 的新增功能在 Android Studio 4.0 中&#xff0c;我们已经对 CPU Profiler 的 UI 做了大量调整来提供更加直观的工作流记录&#xff0c;而在 Android Studio 4.1 中&#xff0c;我们基于开发者们的反馈对此功能进行了持续改进&#xff0c;并且新…

[html] DOM节点的根节点是不是body?

[html] DOM节点的根节点是不是body&#xff1f; 文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述&#xff0c;并定义了一种方式可以使从程序中对该结构进行访问&#xff0c;从而改变文档的结构&#xff0c;样式和内容。DOM 将文档解析为一个由节…

第一节 Memcached分布式缓存入门

关于Memcached的博文太多了&#xff0c;以下是个人学习的收集整理。 本节讨论问题: 简单介绍与应用下载安装注意事项简单测试Memcached分布式原理 一、介绍与应用 在常规的WEB开发下&#xff0c;基本都会利用到缓存用以降低对数据库的压力&#xff0c;提高访问速度。有时候缓存…

tomcat 拦截指定url_一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了

点击“ 程序员内点事 ”关注&#xff0c;选择“ 设置星标 ”坚持学习&#xff0c;好文每日送达&#xff01;周末有个小伙伴加我微信&#xff0c;向我请教了一个问题&#xff1a;老哥&#xff0c;「过滤器 (Filter) 和 拦截器 (Interceptor) 有啥区别啊&#xff1f;」 听到题目我…