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

Java面试题-线程(一)

在典型的 Java 面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程,如何创建线程,用什么方式创建线程比较好(比如:继承 thread 类还是调用 Runnable 接口),然后逐渐问到并发问题像在 Java 并发编程的过程中遇到了什么挑战,Java 内存模型,JDK1.5 引入了哪些更高阶的并发工具,并发编程常用的设计模式,经典多线程问题如生产者消费者,哲学家就餐,读写器或者简单的有界缓冲区问题。

仅仅知道线程的基本概念是远远不够的, 必须知道如何处理死锁,竞态条件,内存冲突和线程安全等并发问
题。

掌握了这些技巧,就可以轻松应对多线程和并发面试了。

本篇 Java面试题-线程(一)
第二篇请戳👉 Java面试题-线程(二)
第三篇请戳👉 Java面试题-线程(三)

线程1/3

    • 1 什么是线程?
    • 2. 线程和进程有什么区别?
    • 3. 如何在 Java 中实现线程?
    • 4 用 Runnable 还是 Thread?
    • 5 Thread 类中的 start () 和 run () 方法有什么区别?
    • 6 Java 中 Runnable 和 Callable 有什么不同?
    • 7 Java 中 CyclicBarrier 和 CountDownLatch 有什么不同?
    • 8 Java 内存模型是什么?
    • 9 Java 中的 volatile 变量是什么?
    • 10 什么是线程安全?Vector 是一个线程安全类吗?
    • 11 Java 中什么是竞态条件?
    • 12 Java 中如何停止一个线程?
    • 13 一个线程运行时发生异常会怎样?
    • 14 如何在两个线程间共享数据?
    • 15 Java 中 notify 和 notifyAll 有什么区别?
    • 16 为什么 wait, notify 和 notifyAll 这些方法不在 thread 类里面?
    • 17 什么是 ThreadLocal 变量?
    • 18 什么是 FutureTask?
    • 19 Java 中 interrupted 和 isInterruptedd 方法的区别?
    • 20 为什么 wait 和 notify 方法要在同步块中调用?

1 什么是线程?

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。

比如,如果一个线程完成一个任务要 100 毫秒,那么用十个线程完成改任务只需 10 毫秒。

Java 在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点。

2. 线程和进程有什么区别?

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

3. 如何在 Java 中实现线程?

在语言层面有两种方式。java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable 接口来执行,由于线程类本身就是调用的 Runnable 接口,所以你可以继承 java.lang.Thread 类或者直接调用 Runnable 接口来重写 run ()方法实现线程。

4 用 Runnable 还是 Thread?

这个问题是上题的后续,大家都知道我们可以通过继承 Thread 类或者调用 Runnable 接口来实现线程,问题是,那个方法更好呢?什么情况下使用它?这个问题很容易回答,如果你知道 Java 不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用 Runnable 接口好了。

5 Thread 类中的 start () 和 run () 方法有什么区别?

这个问题经常被问到,但还是能从此区分出面试者对 Java 线程模型的理解程度。start ()

方法被用来启动新创建的线程,而且 start ()内部调用了 run ()方法,这和直接调用 run ()

方法的效果不一样。当你调用 run ()方法的时候,只会是在原来的线程中调用,没有新的

线程启动,start ()方法才会启动新线程。

6 Java 中 Runnable 和 Callable 有什么不同?

Runnable 和 Callable 都代表那些要在不同的线程中执行的任务。Runnable 从 JDK1.0

开始就有了,Callable 是在 JDK1.5 增加的。它们的主要区别是 Callable 的 call () 方法可

以返回值和抛出异常,而 Runnable 的 run ()方法没有这些功能。Callable 可以返回装载

有计算结果的 Future 对象。

7 Java 中 CyclicBarrier 和 CountDownLatch 有什么不同?

CyclicBarrier 和 CountDownLatch 都可以用来让一组线程等待其它线程。与

CyclicBarrier 不同的是,CountdownLatch 不能重新使用。

8 Java 内存模型是什么?

Java 内存模型规定和指引 Java 程序在不同的内存架构、CPU 和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java 内存模型对一个线程所做的变动能被其它线程可
见提供了保证,它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如,先行发生关系确保了:
线程内的代码能够按先后顺序执行,这被称为程序次序规则。
对于同一个锁,一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前,也叫做管程锁定规则。
前一个对 Volatile 的写操作在后一个 volatile 的读操作之前,也叫 volatile 变量规则。
一个线程内的任何操作必需在这个线程的 start ()调用之后,也叫作线程启动规则。
一个线程的所有操作都会在线程终止之前,线程终止规则。
一个对象的终结操作必需在这个对象构造完成之后,也叫对象终结规则。
可传递性强烈建议大家阅读《Java 并发编程实践》第十六章来加深对 Java 内存模型的理解。

9 Java 中的 volatile 变量是什么?

volatile 是一个特殊的修饰符,只有成员变量才能使用它。在 Java 并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的。volatile 变量可以保证下一个读取操作会在前一个写操作之后发生,就是上一题的 volatile 变量规则。点击这里查看更多volatile 的相关内容。

10 什么是线程安全?Vector 是一个线程安全类吗?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。
如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组,线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的 ArrayList 不是线程安全的。

11 Java 中什么是竞态条件?

举个例子说明。

竞态条件会导致程序在并发情况下出现一些 bugs。多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了,那么整个程序就会出现一些不确定的 bugs。这种 bugs 很难发现而且会重复出现,因为线程间的随机竞争。一个例子就是无序处理。

12 Java 中如何停止一个线程?

Java 提供了很丰富的 API 但没有为停止线程提供 API。JDK 1.0 本来有一些像 stop (),suspend () 和 resume ()的控制方法但是由于潜在的死锁威胁因此在后续的 JDK 版本中他们被弃用了,之后 Java API 的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当 run () 或者 call () 方法执行完的时候线程会自动结束,如果要手动结束一个线程,你可以用 volatile 布尔变量来退出 run ()方法的循环或者是取消任务来中断线程。

13 一个线程运行时发生异常会怎样?

这是我在一次面试中遇到的一个很刁钻的 Java 面试题, 简单的说,如果异常没有被捕获该线程将会停止执行。Thread.UncaughtExceptionHandler 是用于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候 JVM 会使用Thread.getUncaughtExceptionHandler ()来查询线程的 UncaughtExceptionHandler 并将线程和异常作为参数传递给 handler 的 uncaughtException ()方法进行处理。

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

可以通过共享对象来实现这个目的,或者是使用像阻塞队列这样并发的数据结构。在两个线程间共享对象)用 wait 和 notify 方法实现生产者消费者模型。

15 Java 中 notify 和 notifyAll 有什么区别?

这又是一个刁钻的问题,因为多线程可以等待单监控锁,Java API 的设计人员提供了一些方法当等待条件改变的时候通知它们,但是这些方法没有完全实现。notify ()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地。而 notifyAll ()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。

16 为什么 wait, notify 和 notifyAll 这些方法不在 thread 类里面?

这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的时候,你要说明为什么把这些方法放在 Object 类里是有意义的,还有不把它放在 Thread 类里的原因。一个很明显的原因是 JAVA 提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。如果线程需要等待某些锁那么调用对象中的 wait ()方法就有意义了。如果 wait ()方法定义在 Thread 类中,线程正在等待的是哪个锁就不明显了。简单的说,由于 wait,notify 和 notifyAll 都是锁级别的操作,所以把他们定义在 Object 类中因为锁属于对象。

17 什么是 ThreadLocal 变量?

ThreadLocal 是 Java 里一种特殊的变量。每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了。它是为创建代价高昂的对象获取线程安全的好方法,比如可以用 ThreadLocal 让 SimpleDateFormat 变成线程安全的,因为那个类创建代价高昂且每次调用都需要创建不同的实例所以不值得在局部范围使用它,如果为每个线程提供一个自己独有的变量拷贝,将大大提高效率。首先,通过复用减少了代价高昂的对象的创建个数。其次,你在没有使用高代价的同步或者不变性的情况下获得了线程安全。线程局部变量的另一个不错的例子是 ThreadLocalRandom 类,它在多线程环境中减少了创建代价高昂的 Random 对象的个数。

18 什么是 FutureTask?

在 Java 并发程序中 FutureTask 表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回,如果运算尚未完成 get 方法将会阻塞。一个 FutureTask 对象可以对调用了 Callable 和 Runnable 的对象进行包装,由于 FutureTask 也是调用了 Runnable 接口所以它可以提交给 Executor 来执行。

19 Java 中 interrupted 和 isInterruptedd 方法的区别?

interrupted () 和 isInterrupted ()的主要区别是前者会将中断状态清除而后者不会。Java 多线程的中断机制是用内部标识来实现的,调用 Thread.interrupt ()来中断一个线程就会设置中断标识为 true。当中断线程调用静态方法 Thread.interrupted ()来检查中断状态时,中断状态会被清零。而非静态方法 isInterrupted ()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛出 InterruptedException 异常的方法都会将中断状态清零。无论如何,一个线程的中断状态有有可能被其它线程调用中断来改变。

20 为什么 wait 和 notify 方法要在同步块中调用?

主要是因为 Java API 强制要求这样做,如果你不这么做,你的代码会抛出IllegalMonitorStateException 异常。还有一个原因是为了避免 wait 和 notify 之间产生竞态条件。

相关文章:

Java面试题-线程(一)

在典型的 Java 面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程,如何创建线程,用什么方式创建线程比较好(比如:继承 thread 类还是调用 Runnable 接口),…...

一篇普通的bug日志——bug的尽头是next吗?

文章目录[bug 1] TypeError: method object is not subscriptable[bug 2] TypeError: unsupported format string passed to numpy.ndarray.__format__[bug 3] ValueError:Hint: Expected dtype() paddle::experimental::CppTypeToDataType<T>::Type()[bug 4] CondaSSLE…...

Vue 3 第八章:Watch侦听器

文章目录Watch侦听器1. 基础概念1.1. Watch的基本用法例子1&#xff1a;监听单个ref的值&#xff0c;直接监听例子2&#xff1a;监听多个ref的值&#xff0c;采用数组形式例子3&#xff1a;深度监听例子4&#xff1a;监听reactive响应式对象单一属性&#xff0c;采用回调函数的…...

GlassFish的安装与使用

一、产品下载与安装glassfish下载地址&#xff1a;https://download.oracle.com/glassfish/5.0.1/release/index.html下载后解压即完成安装&#xff0c;主要目录说明&#xff1a;bin目录&#xff1a;为asadmin命令所在目录。glassfish为主目录&#xff1a;glassfish\bin目录为命…...

【java】Java 重写(Override)与重载(Overload)

文章目录重写(Override)方法的重写规则Super 关键字的使用重载(Overload)重载规则实例重写与重载之间的区别总结重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变&#xff0c;核心重写&#xff01; 重写的好处在于…...

OpenCV-PyQT项目实战(12)项目案例08:多线程视频播放

欢迎关注『OpenCV-PyQT项目实战 Youcans』系列&#xff0c;持续更新中 OpenCV-PyQT项目实战&#xff08;1&#xff09;安装与环境配置 OpenCV-PyQT项目实战&#xff08;2&#xff09;QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战&#xff08;3&#xff09;信号与槽机制 …...

面向对象设计模式:结构型模式之装饰器模式

文章目录一、引入二、装饰器模式2.1 Intent 意图2.2 Applicability 适用性2.3 类图2.4 优缺点2.5 应用实例&#xff1a;Java IO 类2.6 应用实例&#xff1a;咖啡馆订购系统一、引入 咖啡馆订购系统 Initial 初始 4 种咖啡 House blend (混合咖啡)Dark Roast (深度烘培)Decaf (…...

Unity iOS 无服务器做一个排行榜 GameCenter

排行榜需求解决方案一(嗯目前只有一)UnityEngine.SocialPlatformsiOS GameCenterAppStoreConnect配置Unity 调用(如果使用GameCenter系统的面板&#xff0c;看到这里就可以了&#xff09;坑(需要获取数据做自定义面板的看这里)iOS代码Unity 代码吐槽需求 需求&#xff1a;接入…...

现在招个会自动化测试的人是真难呀~你会个锤子的自动化测试

现在招个会自动化测试的人是真难呀~ 前一段时间公司计划要招2个自动化测试到岗&#xff0c;同事面试了十几个来应聘的人&#xff0c;发现一个很奇怪的现象&#xff0c;在面试的时候&#xff0c;如果问的是框架API、脚本编写这些问题&#xff0c;基本上所有人都能对答如流&…...

OracleDatabase——数据库表空间dmp导出与导入

由于公司的程序一直部署在客户现场内网&#xff0c;内网调试难度高&#xff0c;一般是有备份还原数据库的需求&#xff0c;这里简记备份&#xff08;导出&#xff09;数据库dmp文件与恢复&#xff08;导入&#xff09;的步骤。 一、导出dmp文件 exp与expdp命令异同 相同点&a…...

20张图带你彻底了解ReentrantLock加锁解锁的原理

哈喽大家好&#xff0c;我是阿Q。 最近是上班忙项目&#xff0c;下班带娃&#xff0c;忙的不可开交&#xff0c;连摸鱼的时间都没有了。今天趁假期用图解的方式从源码角度给大家说一下ReentrantLock加锁解锁的全过程。系好安全带&#xff0c;发车了。 简单使用 在聊它的源码…...

Dockerfile构建Springboot镜像

Dockerfile构建Springboot镜像 文章目录 Dockerfile构建Springboot镜像 简介实例演示 前期准备 Docker环境Springboot项目Dockerfile文件 Windows 要求构建镜像启动测试 Linux 要求构建镜像启动测试 简介 容器技术大流行的时代&#xff0c;也是docker大流行的时代。 此文…...

从深分页查询到覆盖索引

最近看到一道面试题&#xff0c;如何优化深分页查询 最简单的例子是 select * from web_bill_main limit 30000,10;分页达到30000行&#xff0c;需要把前面29999行都过滤掉&#xff0c;才能找到这10条数据 所以整体时间花了80ms(工具显示时间) 我当时的第一反应是&#xff0…...

Go语言学习的第三天--下部分(Gin框架的基础了解)

每天都会分享Go的知识&#xff0c;喜欢的朋友关注一下。每天的学习分成两部分基础&#xff08;必要的&#xff0c;基础不牢地动山摇&#xff09;&#xff0c;另一部分是Go的一些框架知识&#xff08;会不定时发布&#xff0c;因为小Wei也是一名搬砖人&#xff09;。但是可以保证…...

JDK的动态代理(powernode 文档)(内含源代码)

JDK的动态代理&#xff08;powernode 文档&#xff09;&#xff08;内含源代码&#xff09; 源代码下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87546086 一、动态代理 目录JDK的动态代理&#xff08;powernode 文档&#xff09;&#xff0…...

第1章 多线程基础

第1章 多线程基础 1.1.2 线程与进程的关系 进程可以看成是线程的容器&#xff0c;而线程又可以看成是进程中的执行路径。 1.2 多线程启动 线程有两种启动方式&#xff1a;实现Runnable接口&#xff1b;继承Thread类并重写run()方法。 执行进程中的任务时才会产生线程&a…...

Linux基本指令(一)

文章目录文件操作文档操作系统管理网络通信备份压缩Ctrl Alt T 打开终端 文件操作 1.复制文件 cp afile bfile &#xff08;将名为afile的文件复制到名为bfile的文件夹中&#xff0c;如果bfile文件不存在&#xff0c;系统将会创建此文件&#xff0c;如果bfile文件已经存在&a…...

el-dialog子组件在mounted周期内获取不到dom?

el-dialog子组件在mounted周期内获取不到dom&#xff1f;一、问题描述二、分析原因三、猜测正常父子组件在mounted生命周期内可以获得dom 父created—子created—子mounted—父mounted----子updated—父updated 一、问题描述 ** el-dialog控制显示隐藏是css控制的display&…...

第九章 opengl之光照(光照贴图)

OpenGL光照贴图漫反射贴图镜面光贴图光照贴图 一个物体的不同部分是不同的材质&#xff0c;那么会有不同的环境光和漫反射颜色表现。 漫反射贴图 原理就是&#xff1a;纹理。 是对同样的原理使用了不同的名字&#xff1a;其实都是使用一张覆盖物体的图像&#xff0c;让我们能…...

JDK动态代理(powernode CD2207 video)(内含教学视频+源代码)

JDK动态代理&#xff08;powernode CD2207 video&#xff09;&#xff08;内含教学视频源代码&#xff09; 教学视频原代码下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87545977 目录JDK动态代理&#xff08;powernode CD2207 video&#xf…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...