当前位置: 首页 > news >正文

面试宝典进阶之Java线程面试题

T1、【初级】线程和进程有什么区别?

(1)线程是CPU调度的最小单位,进程是计算分配资源的最小单位。
(2)一个进程至少要有一个线程。
(3)进程之间的内存是隔离的,而同一个进程中的线程之间是共享内存的。

T2、【初级】线程的创建有哪几种方式?

(1)继承Thread类,重写run方法。
(2)实现Runnable接口,重写run方法。
(3)实现Callable接口,重写call方法,结合Future创建线程。
(4)通过线程池创建。

T3、【初级】创建线程池的几种方式?

(1)使用Executors工具类创建线程池
(2)直接使用底层线程池构造函数创建线程:new ThreadPoolExecuto()

T4、【中级】线程池的参数有哪些?

    // 五参创建public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}// 七参创建public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {//---}

(1)corePoolSize 核心线程数
(2)maximumPoolSize 最大线程数
(3)keepAliveTime 空闲线程存活时间
(4)unit 空闲线程存活时间单位
(5)workQueue 工作队列

  • ArrayBlockingQueue
  • LinkedBlockingQuene
  • SynchronousQuene
  • PriorityBlockingQueue

(6)threadFactory 线程工厂
(7)handler 拒绝策略

  • 第一种拒绝策略是 AbortPolicy,这种拒绝策略在拒绝任务时,会直接抛出异常 RejectedExecutionException (属于RuntimeException),让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。
  • 第二种拒绝策略是 DiscardPolicy,这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。
  • 第三种拒绝策略是 DiscardOldestPolicy,如果线程池没被关闭且没有能力执行,则会丢弃任务队列中的头结点,通常是存活时间最长的任务,这种策略与第二种不同之处在于它丢弃的不是最新提交的,而是队列中存活时间最长的,这样就可以腾出空间给新提交的任务,但同理它也存在一定的数据丢失风险。
  • 第四种拒绝策略是 CallerRunsPolicy,相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。这样做主要有两点好处。
  • 第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。
  • 第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。
理解思路
  • 队列已满,并且超过最大线程数,直接报异常
  • 队列已满,并且超过最大线程数,抛弃新添加的任务
  • 队列已满,并且超过最大线程数,抛弃最老的任务
  • 队列已满,并且超过最大线程数,交给提交任务的线程来执行

T5、【中级】多线程中常用的工具类有哪些?

(1)CountDownLaunch:让某一条线程等待其他线程执行完毕后再执行
(2)CycleBarrier:希望多条线程准备就绪之后,一起开始执行
(3)Condition:当希望指定唤醒某条线程时使用

T6、【中级】线程池都有哪些类型?

(1)缓存型线程池:

ExecutorService executorService = Executors.newCachedThreadPool();

(2)固定长度线程池

ExecutorService executorService = Executors.newFixedThreadPool(10);

(3)可定时执行的线程池

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);

(4)单线程化线程池

ExecutorService executorService = Executors.newSingleThreadExecutor();
理解思路
  • 定长线程池
  • 变长线程池
  • 单线程池
  • 定时线程池

T7、【中级】线程的状态都有哪些?

线程状态

T8、【中级】synchronized和static synchronized区别?

(1)synchronized是对象锁
(2)static synchronized是类锁

T9、【中级】synchronized与Lock有啥区别?

(1)实现方式不同:synchronized是Java语言内置的关键字,而Lock是一个Java API。

(2)粒度不同:synchronized锁的是整个方法或代码块,而Lock可以只锁定代码的一部分,可以灵活地控制加锁和解锁操作。

(3)可中断性不同:synchronized在获取锁失败时会等待,直到获取锁成功,而Lock可以通过tryLock()方法尝试获取锁,如果获取失败则可以终止等待。

(4)条件变量不同:Lock提供了Condition接口来实现线程之间的协调,而synchronized没有类似的概念。

(5)释放方式不同:synchronized可重入,即同一线程可以重复获取锁并解锁synchronized是自动释放锁。而Lock也可重入,但需要手动管理锁的计数器,Lock需要手动释放锁。

理解记忆
  • synchronized是java内置关键字,自动释放锁,可重入,非公平
  • Lock是接口,手动释放锁,可重入,可公平也可以不公平,默认是不公平
  • synchronized的底层原理是使用了操作系统的互斥对象(mutex)来实现的。

T10、【中级】start()和run()有啥区别?

(1)start()方法来启动线程,真正实现了多线程运行。这时无需等待 run 方法体代码执行完毕,可以直接继续执行下面的代码。
(2)通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。
(3)方法 run()称为线程体,它包含了要执行的这个线程的内容,线程就进入了运行状态,开始运行 run 函数当中的代码。 Run 方法运行结束, 此线程终止。然后 CPU 再调度其它线程。

T11、【初级】wait()和sleep()有啥区别?

(1)调用方式不同:wait()是Object类的方法,可以调用任何对象的wait()方法;而sleep()是Thread类的静态方法,只能调用当前执行线程的sleep()方法。

(2)执行的对象不同:wait()会释放对象锁,线程执行完wait()方法后进入等待池中,只能被其他线程调用notify()或notifyAll()方法唤醒;而sleep()不会释放对象锁,线程暂停一段时间后,会重新进入就绪状态,由操作系统进行调度。

(3)使用方式不同:wait()、notify()和notifyAll()通常用于相互协调的线程之间进行协作,如线程A等待线程B的信号来进行操作;而sleep()通常用于程序中对时间的控制,如在执行某个操作时需要暂停一段时间后再继续执行。

(4)异常处理不同:wait()和sleep()都可以抛出InterruptedException异常,但是InterruptedException异常的含义不同。wait()方法在等待过程中如果线程被中断,则会抛出InterruptedException异常;而sleep()方法在睡眠过程中如果线程被中断,则会清除中断标志位,不会抛出InterruptedException异常。

理解记忆
  • sleep()是静态方法,释放cpu但不释放锁,阻塞到时间了就继续执行
  • wait()是object对象的方法,释放锁,通过notify()唤醒

T12、【初级】notify()和notifyAll()有啥区别?

(1)notify()随机唤醒一条线程;
(2)notifyAll()唤醒全部的线程。

T13、悲观锁和乐观锁有啥区别?

(1)并发控制策略不同:悲观锁采用独占锁(排他锁)的方式,在读写数据之前先获得锁,以保证操作的原子性;而乐观锁采用版本号或时间戳等方式实现数据版本控制,在更新数据之前先检查版本号或时间戳是否一致,以确保在多线程环境下对数据的并发访问正确。

(2)加锁开销不同:悲观锁需要频繁的加锁和解锁,造成了较大的加锁开销和系统资源浪费;而乐观锁只需要在更新操作时进行版本号或时间戳的比较,不需要进行加锁和解锁操作,因此开销较小。

(3)适用场景不同:悲观锁适用于多写少读的情况,例如数据库的更新操作;而乐观锁适用于多读少写的情况,例如缓存中数据的更新。

(4)冲突处理方式不同:悲观锁在获取锁失败时会进入等待队列等待锁的释放,从而避免了数据的冲突问题;而乐观锁在检查版本或时间戳失败时需要回滚事务或重新执行操作,从而处理数据的冲突问题。。

理解记忆
  • 悲观锁,是重锁,是真正使用了锁
  • 乐观锁,是轻量级锁,实际上没有使用锁,而是通过CAS实现的

T14、join和CountDownLatch区别

(1)join:join()是线程对象的成员方法,功能是等待调用join()的线程对象执行完毕,才执行其它的逻辑
(2)CountDownLatch是一种灵活的闭锁实现,它维护了一个计数器,通过计数器控制一个或多个线程等待另一组事件发生,具体控制方法是:CountDownLatch调用countDown方法来递减计数器,表示有一个事件发生了,调用await在计数器为0之前保持阻塞。
(3)区别:
- join()的阻塞原理是不停检查join()所属的线程对象是否存活(也就是线程完全执行完毕),如果存活则让调用join()的线程保持阻塞。
- CountDownLatch的阻塞原理是仅仅关注计数器是否为0,若不为0才保持阻塞,它并不关注持有计数器的其它线程是否完全执行完毕。
显然join()能控制阻塞的范围比CountDownLatch小,且没有CountDownLatch那么灵活。

理解记忆
  • join是线程执行完了,才唤醒
  • CountDownLatch是一个计数器,为0时才唤醒

T15、多线程有哪些特性?

(1)原子性
(2)可见性:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
(3)有序性:通过synchronized和lock来保证有序性

T16、什么是锁?

锁就是在多线程环境下为保证共享资源健康、线程安全的一种手段。
线程操作某个共享资源之前,先对资源加一层锁,保证操作期间没有其他线程访问资源,当操作完成后,再释放锁。

T17、什么是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

T18、怎么避免死锁?

1、避免一个线程同时获取多个锁,如果必须使用多个锁,必须使用相同的加锁顺序。
2、降低锁的使用粒度,尽量保证一个锁只占用一个资源
3、尽可能使用定时锁,例如使用lock.tryLock(timeout)来替代使用内部锁机制

T19、分布式锁实有哪些实现方案?

1、基于数据库(唯一索引)
2、基于缓存(Redis,memcached,tair)
3、基于Zookeeper

T20、你都了解哪些锁?

java锁

相关文章:

面试宝典进阶之Java线程面试题

T1、【初级】线程和进程有什么区别&#xff1f; &#xff08;1&#xff09;线程是CPU调度的最小单位&#xff0c;进程是计算分配资源的最小单位。 &#xff08;2&#xff09;一个进程至少要有一个线程。 &#xff08;3&#xff09;进程之间的内存是隔离的&#xff0c;而同一个…...

BOM简介

1.1 常用的键盘事件 1.1.1 键盘事件 键盘事件触发条件onkeydown按键被按下时触发onkeypress按键被按下时触发onkeyup按键被松开时触发 注意&#xff1a;addEventListener事件不需要加on <script>//1. keydown 按键按下的时候触发,按任意键都触发&#xff0c;也可以识…...

Java中的集合框架

概念与作用 集合概念 现实生活中&#xff1a;很多事物凑在一起 数学中的集合&#xff1a;具有共同属性的事物的总体 java中的集合类&#xff1a;是一种工具类&#xff0c;就像是容器&#xff0c;储存任意数量的具有共同属性的对象 在编程时&#xff0c;常常需要集中存放多个…...

Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行

环境: Rustdesk1.19 问题描述: Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行 解决方案: 1.查看源代码 pub async fn start_all() {crate::hbbs_http::sync::start();let mut nat_tested = false;check_zombie()...

【SPDK】【NoF】使用SPDK部署NVMe over TCP

SPDK NVMe over Fabrics Target是一个用户空间应用程序&#xff0c;通过以太网&#xff0c;Infiniband或光纤通道等结构呈现块设备,SPDK目前支持RDMA和TCP传输。 本文将在已经编译好SPDK的基础上演示如何使用SPDK搭建NVMe over TCP&#xff0c;前提是您已经将一块NVMe硬盘挂载…...

Spring boot 3 集成rocketmq-spring-boot-starter解决版本不一致问题

安装RocketMQ根据上篇文章使用Docker安装RocketMQ并启动之后&#xff0c;有个隐患详情见下文 Spring Boot集成 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2…...

python爬虫实战(6)--获取某度热榜

1. 项目描述 需要用到的类库 pip install requests pip install beautifulsoup4 pip install pandas pip install openpyxl然后&#xff0c;我们来编写python脚本&#xff0c;并引入需要的库&#xff1a; import requests from bs4 import BeautifulSoup import pandas as p…...

十三、K8S之亲和性

亲和性 一、概念 在K8S中&#xff0c;亲和性&#xff08;Affinity&#xff09;用来定义Pod与节点关系的概念&#xff0c;亲和性通过指定标签选择器和拓扑域约束来决定 Pod 应该调度到哪些节点上。与污点相反&#xff0c;它主要是尽量往某节点靠。 亲和性是 Kubernetes 中非常…...

对于网关的理解-Gateway

因为在使用微服务的时候&#xff0c;会有多端请求。会产生以下问题&#xff1a; 1.客户端需要记住每一个微服务的url 2.主机端口也会直接暴露 3.每一个微服务都需要认证 4.存在跨域问题 所以网关可以解决统一访问、隐藏真实的服务器地址、网关进行统一认证、解决跨域问题、…...

win10 - Snipaste截图工具的使用

win10 - Snipaste截图工具的使用 Step 1&#xff1a;下载 下载链接 提取码&#xff1a;wuv2 Step 2&#xff1a;直接解压可用 找到解压好的目录&#xff0c;并双击exe文件即可 Step 3&#xff1a;设置开机启动 在电脑右下角找到snipaste图标&#xff0c;右键&#xff0c;找…...

Selenium 学习(0.19)——软件测试之基本路径测试法——拓展案例

1、案例 请使用基本路径法为变量year设计测试用例&#xff0c;year的取值范围是1000<year<2001。代码如下&#xff1a; 2、步骤 先画控制流程图 再转化为控制流图&#xff08;标出节点&#xff09; V(G) 总区域数 4 V(G) E - N 2 (边数 - 节点数 2…...

工作记录-------正则表达式---小白也能看懂

什么是正则表达式 正则表达式是一种强大的工具&#xff0c;用于匹配和识别文本模式。 下面是一个基本的介绍&#xff1a; ^ 和 $: 这些是锚定字符&#xff0c;分别匹配字符串的开头和结尾。例如&#xff0c;^Hello匹配以 “Hello” 开头的字符串&#xff0c;end$匹配以 “en…...

C3-1.3.1 无监督学习——异常检测

C3-1.3.1 无监督学习——异常检测 1、举例&#xff1a;异常值检测示例——密度评估法 1.1 举一个例子 这里做的是 查看飞机发动机 异常检测&#xff1a; 左侧&#xff1a;X1 ,X2 … 是 可能会影响发动机状态的特征右侧&#xff1a; Dataset&#xff1a;训练数据集New engine…...

1.4.1机器学习——梯度下降+α学习率大小判定

1.4.1梯度下降 4.1、梯度下降的概念 ※【总结一句话】&#xff1a;系统通过自动的调节参数w和b的值&#xff0c;得到最小的损失函数值J。 如下&#xff1a;是梯度下降的概念图。 我们有一个损失函数 J(w,b)&#xff0c;包含两个参数w和b&#xff08;你可以想象成J(w,b) w*x…...

在IntelliJ IDEA中,.idea文件是什么,可以删除吗

相信有很多小伙伴&#xff0c;在用idea写java代码的时候&#xff0c;创建工程总是会出现.idea文件&#xff0c;该文件也从来没去打开使用过&#xff0c;那么它在我们项目里面&#xff0c;扮演什么角色&#xff0c;到底能不能删除它呢&#xff1f; 1、它是什么&#xff1f;有什么…...

【Spring Cloud】Gateway组件的三种使用方式

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Cloud》。&#x1f3af;&#x1f3af; &am…...

对象的复制

方式一&#xff1a;sv 的new函数 trans tr1,tr2; malbox.get(tr2); tr1 new tr2;//仅用于浅拷贝&#xff0c;拷贝后tr1,tr2为两个独立的对象方式二&#xff1a;uvm 域的自动化常用函数&#xff1a;copy / clone / 使用前提&#xff1a; 1. 函数都可用于uvm_object类型&…...

基于 Python+Neo4j+医药数据,构建了一个知识图谱的自动问答系统

知识图谱是目前自然语言处理的一个热门方向。目前知识图谱在各个领域全面开花&#xff0c;如教育、医疗、司法、金融等。 本项目立足医药领域&#xff0c;以垂直型医药网站为数据来源&#xff0c;以疾病为核心&#xff0c;构建起一个包含7类规模为4.4万的知识实体&#xff0c;…...

Maven之属性管理

1.属性管理 1.1 属性配置与使用 ①&#xff1a;定义属性 <!--定义自定义属性--> <properties><spring.version>5.2.10.RELEASE</spring.version> </properties>②&#xff1a;引用属性 <dependency><groupId>org.springframewor…...

快乐学Python,数据分析之获取数据方法「公开数据或爬虫」

学习Python数据分析&#xff0c;第一步是先获取数据&#xff0c;为什么说数据获取是数据分析的第一步呢&#xff0c;显而易见&#xff1a;数据分析&#xff0c;得先有数据&#xff0c;才能分析。 作为个人来说&#xff0c;如何获取用于分析的数据集呢&#xff1f; 1、获取现成…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...

Windows 下端口占用排查与释放全攻略

Windows 下端口占用排查与释放全攻略​ 在开发和运维过程中&#xff0c;经常会遇到端口被占用的问题&#xff08;如 8080、3306 等常用端口&#xff09;。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口&#xff0c;帮助你高效解决此类问题。​ 一、准…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...