面试系列之线程篇

2023-10-31

线程和进程?

进程是资源分配和调度的最小独立单元,线程是CPU调度的基本单元;

一个进程可以包含多个线程,多个线程共享该进程的资源;

线程可以看作是轻量级的进程;

 

进程间通信的方式?

volatile,synchronized,wait/notifyAll,管道输入/输出流,thread.join(),ThreadLocal

 

聊聊synchronized和lock?

synchronized是Java中的一个关键字,通过该关键字修饰来达到同步的效果,被synchronized修饰的代码块会隐式的加锁解锁,对开发者都是透明的,底层是基于进入和退出Monitor对象来实现的同步,会在代码块前后形成monitorenter和monitorexit两条指令,分别进行加锁解锁(可重入锁);

进入时执行monitorenter获取锁计算器+1,退出时执行monitorexit计数器-1;

lock则是一个对象锁,开发者需要显式的获取锁释放锁,常见的有ReentrantLock,lock对象锁是一种支持可中断的锁,而synchronized则不支持,lock在发生异常时如果没有主动的去释放锁会导致死锁;synchronized会自动释放异常线程占有的锁,不会发生死锁;

lock可以获取锁的状态,synchronized不可以;

 

wait和sleep的区别?

wait和sleep都是针对线程的,都可以达到让线程等待或者说暂时性停止的效果,但是这两个方法又是不同的,主要体现在下面几点:

  • wait方法是Object类的,sleep是线程类(Thread)的静态方法

  • wait执行等待释放锁,sleep睡眠不释放锁

  • wait需要被notify/notifyAll唤醒,sleep时间失效后会自动唤醒

 

如何指定多个线程的执行顺序?

设定一个tempNumber用来指定当前获得执行机会的线程编号,每个线程执行完就更新这个number,指明下一个要有执行权利的线程,同时唤醒所有等待的线程;

每个线程启动之后,写一个while判断tempNumber是否等于自己的number值,如果不是则wait,否则就执行线程;

 

多线程产生死锁的4个必要原因?

互斥条件:一个资源每次只能被一个线程使用;

请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放,就例如AB线程各自持有对方的锁,却需要等待对方释放锁才能释放自己的锁;

不剥夺条件:线程已经获得了资源,在没有结束之前,不允许其他线程获得资源,也就是线程对共享资源的独占性;

循环等待条件:多个线程之间形成环形等待的情况,即多个线程陷入死循环;

如何避免死锁?

指定线程获取锁的顺序即可避免死锁,同一时刻只能有且仅有唯一一个线程获得锁的机会;

 

聊聊你对volatile的认识?

该关键字可以保证变量的可见性,但是不保证原子性;

被volatile修饰的变量,当线程处理时,会将线程本地内存设置为无效,强制要求线程去主内存操作变量;

被volatile修饰的变量在操作时会通过生成lock指令来形成内存屏障,禁止JVM进行指令重排序操作;

 

谈谈你对ThreadLocal的理解?

当使用 ThreadLocal 维护变量时,为每个使用该变量的线程提供了一份独立的变量副本,所以每一个线程都可以独立的操作自己的副本,而不会影响其他线程对应的副本;

ThreadLocal内部实现机制:每个线程内部都维护一个ThreadLocalMap,每个ThreadLocalMap又包含若干个Entry,Entry 的 Key 是一个 ThreadLocal 实例,Value 是一个线程特有对象。Entry 的作用是为所属线程建立起一个 ThreadLocal 实例与一个线程特有对象之间的对应关系;

 

聊聊CountDownLatch和CyclicBarrier

作用:用于监听某些初始化操作,等待初始化执行完毕,通知主线程继续工作。允许一个或多个线程等待其他线程完成操作;

怎么做:CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务;

CountDownLatch的await()方法,会使线程等待,直到计数器为0,结束等待

CountDownLatch的countDown()计数器 -1

 

CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续执行;

CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次;

 

聊聊Semaphore?

信号量是用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用公共资源

 

聊聊Exchanger?

Exchanger主要是用于线程之间进行数据交换的,提供一个同步点,在这个同步点,两个线程可以交换彼此的数据;两个线程通过Exchanger方法来进行交换,当第一个线程先执行Exchanger()方法,他会一直等待第二个线程也执行Exchanger方法,然后两个线程交换数据;

 

聊聊Java实现原子操作的CAS?

CAS:又称无锁算法,全称Compare-and-Swap(比较并交换),依赖处理器的汇编指令cmpxchg(比较交换)来完成,当CAS指令执行时,当且仅当内存位置V符合旧预期值时A时,处理器才会用新值B去更新V的值,否则就不执行更新,但是无论是否更新V,都会返回V的旧值,该操作过程就是一个原子操作;

什么是CAS的BAB问题,如何解决?

使用CAS时因为会先去检查内存位置的旧值A有没有发生变化,发生变化则更新最新值B,但是存在一种情况就是,初次读取内存旧值时是A,再次检查之前这段期间,如果内存位置的值发生过从A变成B再变回A的过程,我们就会错误的检查到旧值还是A,认为没有发生变化,其实已经发生过A-B-A得变化;

ABA解决方案:使用版本号,即1A-2B-3A,这样就会发现1A到3A的变化,不存在ABA变化无感知问题,JDK的atomic包中提供一个带有标记的原子引用类AtomicStampedReference来解决ABA问题,它可以通过控制变量值得版本号来保证CAS的正确性。该类的compareAndSet方法会首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果都相等则以原子方式该引用和该标志的值进行更新;

 

聊聊队列同步器AQS?

队列同步器是用来构建锁或者其他同步组件的基础元素,主要是使用一个int成员变量来表示同步状态,通过一个FIFO队列来完成资源的获取线程的排队工作,队列同步器是面向锁的实现的;

同步器依赖内部的同步队列(FIFO)来完成同步状态的管理,过程如下:当前线程获取同步状态失败时,同步器就会将当前线程以及等待状态的信息构成一个节点并加入到同步队列中,同时阻塞当前线程,当同步状态释放时,会将首节点的线程唤醒,再次尝试获取同步状态;

 

聊聊你所熟悉的并发容器有哪些?

ConcurrentHashMap:线程安全高效的HashMap,内部采用锁分段技术来优化,每个段其实就是一个小的HashTable,他们有自己各自的锁,只要多个修改操作发生在不同的段上,他们之间就可以并发的进行;

ConcurrentLinkedQueue:一个基于链表节点实现的无界限安全队列(不允许Null元素存在,有null存在则链表就会断了),该队列的元素遵循先进先出(FIFO)原则,它采用了无等待算法(CAS)来实现,不会发生阻塞,适用于高并发场景;

BlockingQueue:支持阻塞的插入和移除操作的队列,这是一个接口,具体有下面几种实现类:

  • ArrayBlockingQueue :由数组结构组成的有界阻塞队列;

  • LinkedBlockingQueue :由链表结构组成的有界阻塞队列;

  • PriorityBlockingQueue :支持优先级排序的无界阻塞队列;

  • DelayQueue:使用优先级队列实现的无界阻塞队列;

  • SynchronousQueue:不存储元素的阻塞队列;

  • LinkedTransferQueue:链表结构组成的无界阻塞队列;

  • LinkedBlockingDeque:链表结构组成的双向阻塞队列;

 

Java提供的线程池有哪几种?

线程池在JDK的JUC包下有个线程池工厂类Executors,通过这个工厂类我们可以创建多种不同的线程池实例,主要有下面4种:

  • newFixedThreadPool(corePoolSize):该方法返回一个固定数量的线程池,线程数量始终不变,当有任务提交时,若线程池中有空闲线程,则立即执行,若没有,则会被缓存在一个任务队列中等待有空闲的线程再去执行;(核心线程数等于最大线程数,默认空闲时间为0,空闲立马销毁);

  • newSingleThreadExecutor():创建一个线程数量始终为1的线程池,若空闲则执行,否则入队列等待被执行;(核心线程数量为1,最大线程数量也为1,空闲等待时间为0);

  • newCachedThreadPool():返回一个可根据实际情况调整线程个数的线程池,不限制最大线程数量,若有任务则没线程时则创建线程,每个线程空闲等待时间为60秒,60秒后如果该线程没有任务可执行,则被回收;(核心线程数量为0,最大线程数量为最大,空闲等待时间为60s);

  • newScheduledThreadPool(corePoolSize):返回一个ScheduledExecutorService对象,该线程池可以指定线程数量,他调了父类super的方法里面还是一个ThreadPoolExecutor,这种方式创建的线程池中每个线程都有定时器的功能;

 

线程池的工作原理是什么?

我们创建一个线程池之后可以通过submit方法向线程池提交任务,线程池内部维护的工作者线程的数量就是该线程池的线程池大小,有 3 种形态:

  • 当前线程池大小:表示线程池中实际工作者线程的数量

  • 最大线程池大小:表示线程池中允许存在的工作者线程的数量上限

  • 核心线程池大小:表示一个不大于最大线程池大小的工作者线程数量上限

新任务提交给线程池时:首先判断线程池中是否有空闲线程,如果有则直接使用线程;如果没有则判断线程池当前线程数是否小于核心线程池,小于则创建新的线程,否则加入到等待队列中排队;当等待队列满时,则判断总线程数是否超过最大线程池大小,如果没有则创建新的线程,如果有则采取拒绝策略;

JDK提供的线程池的拒绝策略有哪些?

  • AbortPolicy策略:该策略直接抛出异常,阻止系统工作;

  • CallerRunsPolicy策略:只要线程池未关闭,该策略直接在调用者线程中运行当前被丢弃的任务。显然这样不会真的丢弃任务,但是,调用者线程性能可能急剧下降;

  • DiscardOledestPolicy策略:丢弃最老的一个请求任务,并尝试再次提交当前任务;

  • DiscardPolicy策略:默默的丢弃无法处理的任务,不予任何处理,当做什么都没发生的样子;

 

如何自定义线程池?

public ThreadPoolExecutor(int corePoolSize, //线程池核心线程数量
                 int maximumPoolSize, //最大线程数量
                 long keepAliveTime, //线程空闲等待时间
                 TimeUnit unit, //线程空闲等待时间的单位
                 BlockingQueue<Runnable> workQueue, //存放待执行任务的队列即等待队列
                 RejectedExecutionHandler handler ) { //拒绝任务的处理策略
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), handler);
   }

 

线程的生命周期中,状态是如何转移的?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面试系列之线程篇 的相关文章

  • Application.persistentDataPath

    今天研究一下Application persistentDataPath 做个案例 如下 使用persistentDataPath可以在真实手机上临时保存一些数据 经过测试在真实手机上是不能够使用Application streamingA
  • PTA 2-7-8 约瑟夫环 (25 分)

    循环链表解法 2 7 8 约瑟夫环 25 分 N个人围成一圈顺序编号 从1号开始按1 2 3 顺序报数 报p者退出圈外 其余的人再从1 2 3开始报数 报p的人再退出圈外 以此类推 请按退出顺序输出每个退出人的原序号 输入格式 输入只有一行
  • 手把手教你用PyTorch从零搭建图像分类模型

    https zhuanlan zhihu com p 38236978 过去的这几年 陆陆续续出现了不少深度学习框架 而在这些框架中 Facebook 发布的 PyTorch 相对较新且很独特的一个 由于灵活 迅速 简单等特点 PyTorc
  • 【sklearn】线性回归、最小二乘法、岭回归、Lasso回归

    文章目录 机器学习的sklearn库 一 回归分析 lt 1 1 gt 线性回归 1 1 1 Python实现线性回归 lt 1 2 gt 最小二乘法 1 2 1 MATLAB实现最小二乘法 1 2 2 MATLAB实现最小二乘法 矩阵变换
  • 五个阶段,了解产品设计流程

    谈到产品设计流程 其实是在谈论最符合当前环境 已有资源下的产品创造模式 从这个角度来说 产品设计流程必然是从已有经验提炼出来的核心知识体系 结合自己UI设计 前端开发 产品经理三个维度的实践经验 尝试将产品设计流程大致分为五个阶段 认知分析
  • 面向对象(多态)

    面向对象 多态 一 多态 同一个对象具有多种形态 二 作用 核心在于方法的重写 覆写 使多种数据类型进行统一 让程序具有超强的扩展性 三 模拟人物进行网络游戏 类图 创建游戏父类 public class Game public void
  • 一个使用MongoDB和Fuse开发的虚拟文件系统

    https sourceforge net projects gridfs fuse files source navbar 以前基于这个Demo开发了一个文件系统 记录一下
  • idea 找不到tomcat、Application Servers配置

    idea 找不到tomcat Application Servers配置 在网上找到的解决方式是File Settings Plugins 中搜索tomcat 如上图显示 我本地已经安装tomcat插件了 又在网上找到说File Setti
  • PAL制搜台

    PAL电视制式 PAL电视制式 Phase Alternating Line 采用625线制式 视讯制式采用PAL B G PAL D K PAL I等 PAL电视不像NTSC制式有中心频点 它采用宽带的频率范围进行电视信号的调制和传输 P
  • Windows在命令行中直接使用conda虚拟环境以及一些实用的conda命令

    在命令行中输入conda env list 可以查看当前已有的全部conda虚拟环境 如下图 输入conda create n name python version可以创建指定python版本的名称为name的虚拟环境 输入conda c
  • Linux常用命令-2

    为了掌握本关知识 你需要掌握 Linux文件操作之创建文件 删除文件 Linux文件夹操作之创建文件夹 删除文件夹 文件和文件夹拷贝 移动 重命名 Linux文件操作 Linux系统中最常用的文件操作有创建 删除文件等 创建文件 linux
  • 【LaTeX Workshop】VS Code 与 SumatraPDF 双向链接配置方法

    TeX Live 2021 Sumatra PDF v3 4 6 64 bit VS Code v1 62 3 system setup LaTeX Workshop v8 22 0 SumatraPDF 配置 安装 SumatraPDF
  • luckysheet使用——导出并下载excel数据及钩子函数的使用等

    这里记录一些常用的API 包括对于获取整个在线excel的数据 使用钩子函数等 获取Excel数据luckysheet getAllSheets 可以将获取到的数据传递到后端通过JSONArray来获取 它是一个一个的sheet页对象的数组
  • C语言基础入门48篇_15_条件运算符(expr1?expr2:expr3,三元运算符,

    条件运算符是C语言中唯一的三元运算符 其基本形式为 expr1 expr2 expr3 一个条件运算符它需要三个表达式 如果expr1的值为非0 则整个条件表达式的值为expr2 如果expr1的值为0 则整个条件表达式的值为expr3 1
  • java和c++区别

    java string类写在heap中 无法修改 c 放在text区 可以修改 java 的块内镶嵌的块不允许变量名重复 c 允许 实行就近法则 转载于 https www cnblogs com bloomingFlower p 1161

随机推荐

  • saltstack之系统初始化状态编写

    saltstack之系统初始化状态编写 1 目录结构 2 关闭selinux 3 关闭防火墙 4 时间同步 chrony 5 内核优化与文件描述 6 ssh服务优化 7 精简开机系统服务 8 历史记录优化 设置终端超时时间 9 yum源 1
  • 数据库基础知识(MySQL入门)

    数据库基础知识 MySQL入门 文章目录 数据库基础知识 MySQL入门 一 基本概念 二 特点 一 基本概念 Information 信息是对客观世界中各种事物的运动状态和变化的反映 是数据的含义 Data 数据用来记录信息的可识别符号
  • java基本语法题目_JAVA的语法基础 练习题

    1 编写Java程序 声明两个int型变量 运用三元运算符判断两个变量是否相等 若不相等 求出两个数中较大的 public class 练习题 public static void main String args int a 10 int
  • 验证集准确率上不去_经验之谈|处理不平衡数据集的7个技巧

    作者 Ye Wu Rick Radewagen编译 ronghuaiyang 介绍 具体的领域中的数据集是什么样的 银行中的欺诈检测 市场中的实时投标 网络中的入侵检测 常见吗 这些领域中的数据 常常只有不到1 的少数 但是 有兴趣 的事件
  • jmeter 固定定时器

    固定定时器 Constant Timer 是一个定时器元件 可以在线程组中的每个线程之间添加固定的延迟时间 固定定时器会对每个线程的执行进行一定的暂停 聊一下和线程组中的调度器对线程组执行时长的影响 相同 都会影响线程组的运行时长 不同 固
  • 加载动态库失败(loadLibrary返回为空 GetLastError126)解决办法 dll有依赖的dll缺失

    问题 加载动态库失败 loadLibrary返回为空 排除 64位也对 平台相同 错误 至少找不到一个必需的隐式或转发依赖项 这个不影响 SmartPay PGL dll下的四个dll 则是他所依赖的四个dll 因为我这里有缺失 显示黄色的
  • 本地ubuntu22.04装cuda11.7+torch2.0.1流程记录

    想要更新cuda11 7 需要的驱动最低版本515 65 01 而我的电脑原驱动为470 需要更新 1 卸载原驱动 使用了命令 sudo apt get purge nvidia sudo apt get autoremove 用以下命令检
  • MATLAB矩阵乘法14例

    MATLAB矩阵乘法14例 简介 矩阵乘法是线性代数中的基本运算之一 也是MATLAB中的重要运算 矩阵乘法的结果是两个矩阵的乘积 其中一个矩阵的列数等于另一个矩阵的行数 在这篇文章中 我们将介绍20个MATLAB矩阵乘法的例子 帮助您更好
  • 什么是自动化测试框架?我们该如何搭建自动化测试框架?

    无论是在自动化测试实践 还是日常交流中 经常听到一个词 框架 之前学习自动化测试的过程中 一直对 框架 这个词知其然不知其所以然 最近看了很多自动化相关的资料 加上自己的一些实践 算是对 框架 有了一些理解 这篇博客 就聊聊自动化框架的一些
  • 根因定位FluxRank论文通过核密度估计(KDE)获得变化量部分

    II CHANGE QUANTIFICATION CHANGE QUANTIFICATION说明 A 变化开始时间 B 变化程度 论文 FluxRank A Widely Deployable Framework to Automatica
  • Mybatis之分页插件PageHelper工作原理

    前言 数据分页功能是软件系统中必备的功能 在持久层使用mybatis的情况下 pageHelper来实现后台分页则是我们常用的一个选择 所以本文专门介绍下 需要的依赖
  • Spring Boot 实现用户行为记录的四种方式

    目录 一 需求背景 二 需要的pom依赖 三 AOP切面编程实现 四 Interceptor拦截器实现 五 Filter过滤器实现 六 ArgumentResolver 七 拓展部分 八 参考文献 一 需求背景 根据产品经理要求 需要对用户
  • npx mkdirp命令

    npx是什么 npx 是 npm v5 2 0引入的一条命令 更方便开发者使用包内提供的命令行工具 ep1 npm原方式 npm install g create react app create react app my app npx方
  • 行为型模式-状态模式(State)

    概述 当一个对象的内在状态改变时允许改变其行为 这个对象看起来像是改变了其类 定义 状态模式的核心理念就是将不同状态对应的行为封装到状态中 在状态变化时改变依赖状态对象的行为 那种在一个方法内对状态进行多重判断的方式 虽然可以根据不同的状态
  • Android系统启动流程(八)——Launcher启动

    1 概述 Launcher是Android的桌面应用 也是一个系统初始化完成之后自动拉起的应用 Launcher会在SystemServer进程初始化完成之后 在ActivityManagerService的systemReady方法中开始
  • 图算法(二十五):子图匹配(Subgraph Matching)【基本的图查询操作,意在发掘图重要的子结构】【适用场景:社交网络分析、群体发现、异常检测】【在一个给定的大图里找到与给定小图同构的子图】

    一 概述 子图匹配 subgraph matching 算法的目的是在一个给定的大图里面找到与一个给定小图同构的子图 这是一种基本的图查询操作 意在发掘图重要的子结构 适用场景 子图匹配 subgraph matching 算法适用于社交网
  • Routh-Hurwitz Criterion 劳斯稳定判据

    Routh Hurwitz Criterion 为什么仅仅要有一个极点在右半平面 那么系统就不会稳定 比如H s 1 s 1 1 s 3 1 s 2 这里有个极点s 2 在有半平面 通过laplace 反变换能够知道 当时间足够长的时候 A
  • [Unity]Crest Ocean System增加海面透明度

    原因 插件没有设置海面透明度的功能 修改shader可以修改透明度 解决方案 关键代码 Shader Ocean shader Shader Crest Ocean SubShader Pass half4 Frag const Varyi
  • FreeSwitch模式:Inbound和Outbound的区别

    14 Inbound和Outbound Outbound模式相较于嵌入式语言相比更强大 适合控制单腿的呼叫 实现复杂的IVR应用 而Inbound更适合接收所有的事件 与多条腿进行交互 进行更复杂的呼叫控制 其中 在Outbound模式中
  • 面试系列之线程篇

    线程和进程 进程是资源分配和调度的最小独立单元 线程是CPU调度的基本单元 一个进程可以包含多个线程 多个线程共享该进程的资源 线程可以看作是轻量级的进程 进程间通信的方式 volatile synchronized wait notify