面试题003-Java-Java多线程(上)

面试题003-Java-Java多线程(上)

目录

  • 面试题003-Java-Java多线程(上)
    • 题目自测
    • 题目答案
      • 1. 什么是线程和进程? 线程与进程的关系和区别?
      • 2. 为什么要使用多线程?
      • 3. 什么是线程上下文切换?
      • 4. 什么是线程死锁? 如何避免死锁?
      • 5. 乐观锁和悲观锁了解么?如何实现乐观锁?
      • 6. 说说 sleep() 方法和 wait() 方法区别和共同点?
      • 7. 讲一下 JMM(Java 内存模型) ?
      • 8. Java 内存区域和 JMM 有何区别?
      • 9. Java中如何创建线程?
      • 10. 实现Runnable接口和实现Callable接口的区别?
    • 参考资料

题目自测

  • 1. 什么是线程和进程? 线程与进程的关系和区别?
  • 2. 为什么要使用多线程?
  • 3. 什么是线程上下文切换?
  • 4. 什么是线程死锁?如何避免死锁?
  • 5. 乐观锁和悲观锁了解么?如何实现乐观锁?
  • 6. 说说 sleep() 方法和 wait() 方法区别和共同点?
  • 7. 讲一下 JMM(Java 内存模型) ?
  • 8. Java 内存区域和 JMM 有何区别?
  • 9. Java中如何创建线程?
  • 10. 实现Runnable接口和实现Callable接口的区别?

题目答案

1. 什么是线程和进程? 线程与进程的关系和区别?

答:进程是程序一次执行的过程,系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程是程序执行的最小单位,一个进程可以产生多个线程,线程可以共享其进程的资源。
线程与进程的关系:一个进程可以包含多个线程,线程是进程的一部分。线程共享进程的资源,进程之间相互独立。
线程和进程的区别:进程有独立的内存空间,线程共享进程的内存空间。进程间通信复杂,线程可以通过共享内存进行通信速度快。进程独立性强安全性高,线程独立性相对较弱,一个线程崩溃可能导致整个程序崩溃。

2. 为什么要使用多线程?

答:提高性能和响应速度,多线程可以使程序同时执行多个任务,从而充分利用多核处理器的能力,提高程序的执行效率。如一个多线程的Web服务器可以同时处理多个客户端请求。
更好的利用资源,在多核处理器环境下,多线程可以让多个CPU核心并行工作。在单核处理器上,多线程可以让某些任务等待I/O操作时执行其他任务,从而更高效的利用CPU时间。

3. 什么是线程上下文切换?

答:线程上下文切换是指操作系统在多线程任务处理中,将CPU从一个线程切换到另外一个线程的过程。在这个过程中,操作系统需要保存当前线程的状态也称上下文(程序计数器、堆栈信息等),然后加载另外一个线程的状态,以便该线程可以继续执行。
出现线程切换的情况:

  • 时间片用完:操作系统将CPU时间划分为多个时间片,每个线程会被分配一个固定的时间片,当时间片用完,操作系统会进行上下文切换,让其他线程活动CPU时间。
  • 阻塞操作:当线程执行阻塞操作(如等待I/O操作完成、执行slepp()、wait()、等待同步锁等)时,它会主动放弃CPU的使用权,进入阻塞状态。
  • 中断处理:当硬件发生中断时(如键盘输入、定时器触发),操作系统需要处理当前线程的执行,以处理中断。
  • 线程优先级变化:当某个线程的优先级发生变化时(如通过调用线程的setPriority()方法),作系统可能会进行上下文切换,将CPU分配给这个高优先级的线程。这种调度策略称为抢占式调度。

4. 什么是线程死锁? 如何避免死锁?

答:线程死锁是指两个或多个线程在执行的过程中,因相互持有对方所需要的资源而处于等待状态,导致所有线程都无法执行继续的情况。具体表现为,每个线程都在等待其他线程释放资源,而每个线程又都持有其他线程所需的资源,从而形成一个等待环路,造成永久阻塞。
死锁的四个必要条件:

  • 互斥:至少有一个资源必须是非共享的,即一次只能由一个线程使用。
  • 占有且等待:个线程已经持有至少一个资源,同时等待获取其他被其他线程持有的资源。
  • 不可剥夺:资源不能被强行剥夺,必须由持有线程显示释放。
  • 循环等待:发生死锁时,涉及的所有线程必定存在一个循环等待资源的链。
    避免死锁的方法:
  • 资源有序分配:为资源分配一个全局顺序,所有线程按照这个顺序请求资源,可以避免发生循环等待。
  • 避免嵌套锁:尽量避免一个线程同时持有多个锁,减少嵌套锁的使用。
  • 限时等待:如无法在指定时间内获取锁,就放弃请求并释放已经持有的锁。
  • 死锁检测和恢复:使用JVM提供的工具或第三方库来监控和检测死锁。
  • 资源预先分配:确保线程在开始执行前就已经获取到所需的所有资源。

5. 乐观锁和悲观锁了解么?如何实现乐观锁?

答:乐观锁和悲观锁这两种锁策略用于解决并发控制问题。
悲观锁是一种假设最坏情况的锁策略,每次在去访问数据时都会认为别人会修改,所以在每次访问数据时都会上锁,这样别人在拿这个数据就会阻塞直到它拿到锁。Java中悲观锁是通过synchronized关键字或Lock接口来实现。
乐观锁是一种假设最好情况的锁策略,每次在去访问数据时都认为别人不会修改,所以不会上锁,但是在修改的时候会去判断有没有人修改这个数据。Java中通常通过版本号机制或者CAS算法来实现。
实现乐观锁的方式:

  • 版本号:在数据库表中添加一个版本号字段,每次更新数据时版本号加1。在更新数据时,将当前版本号作为条件之一进行更新,如果版本号不匹配,则说明数据已经被其他线程修改。
  • CAS:使用一个预期值和要更新的变量值进行比较,两值相等才会进行更新

6. 说说 sleep() 方法和 wait() 方法区别和共同点?

答:slepp()和wait()都可以暂停线程的执行。
两者的区别:

  • sleep() 是 Thread 类的静态方法,wait() 是 Object类的实例方法。
  • sleep() 不会释放锁,wait() 会释放锁进入等待状态、直到被唤醒。
  • sleep() 在指定的时间到期后会自动唤醒,wait() 需要 notify()/notifyAll()方法来唤醒。
  • sleep() 可以在任何地方使用,wait() 必须在同步块或者同步方法中调用。

7. 讲一下 JMM(Java 内存模型) ?

答:Java内存模型是Java虚拟机规范的一部分,它定义了在多线程环境下,Java程序中变量的访问方式。JMM是一种抽象概念,它屏蔽了不同硬件和操作系统内存访问的差异,为Java程序提供了一致的内存访问效果。
JMM分为主内存和工作内存,主内存是所有线程共享的区域,对应于JVM内存区域中的堆。工作内存是JMM抽象的概念,并非真实存在,它对应于JVM中的栈,线程对变量的所有操作都必须在工作内存中进行,不能直接操作主内存中的数据。

8. Java 内存区域和 JMM 有何区别?

答:Java内存区域侧重于JVM如何管理和划分运行时内存区域。Java内存区域有堆、方法区、虚拟机栈、程序计数器、本地方法栈。
JMM侧重于多线程环境下线程与主存之间的交互关系以及变量的访问规则。

9. Java中如何创建线程?

答:Java中创建线程的方式有很多,如继承Thread类、实现Runnable接口、实现Callable接口、使用ExecutorService线程池等等。

  • 继承Thread类:创建一个类来继承Thread类,重写它的run()方法。然后通过创建这个类的实例来创建新的线程,通过调用类实例的start()方法来启动线程。
    class MyThread extends Thread {  public void run() {  System.out.println("线程运行中");  }  
    }  public class ThreadExample {  public static void main(String[] args) {  MyThread t = new MyThread();  t.start(); // 启动线程  }  
    }
    
  • 实现Runnable接口:创建一个类来实现Runnable接口,实现它的run()方法,然后创建Thread类的实例,将Runnable接口实现类的实例作为构造器参数传递,调用Thread类的实例的start()方法启动线程。
    class MyThread extends Thread {  public void run() {  System.out.println("线程运行中");  }  
    }  public class ThreadExample {  public static void main(String[] args) {  MyThread t = new MyThread();  t.start(); // 启动线程  }  
    }
    
  • 实现Callable接口:创建一个Callable接口的实现类,并实现call()方法。然后创建Callable实现类的实例,使用FutureTask类来包装Callable对象,使用FutureTask对象作为Thread对象的target创建并启动新线程,调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
    class MyCallable implements Callable<String> {  public String call() throws Exception {  return "线程执行结果";  }  
    }  public class CallableExample {  public static void main(String[] args) throws Exception {  MyCallable callable = new MyCallable();FutureTask<String> futureTask = new FutureTask<>(callable);new Thread(futureTask).start();System.out.println(futureTask.get()); // 获取结果}  
    }
    

10. 实现Runnable接口和实现Callable接口的区别?

答:他们主要的区别体现在方法签名和返回值、异常处理和提交与执行方式上。

  • 方法签名和返回值:Runnable的run()方法有返回值,Callable的call()方法有返回值。
  • 异常处理:run()方法不能抛出受检异常,只能处理运行时异常。call()方法可以声明抛出异常。
  • 提交和执行:Runnable通过Thread或ExecutorService执行。Callable通过ExcutroService执行,并返回Future对象以获取结果。

参考资料

  • JavaGuide
  • 牛客网-Java面试宝典

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

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

相关文章

哈希表 | 哈希查找 | 哈希函数 | 数据结构 | 大话数据结构 | Java

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;毛毛张今天分享的内容&#x1f586;是数据结构中的哈希表&#xff0c;毛毛张主要是依据《大话数据结构&#x1f4d6;》的内容来进行整理&#xff0c;不…

程序化交易广告及其应用

什么是程序化交易广告&#xff1f; 程序化交易广告是以实时竞价技术即RTB&#xff08;real-time bidding&#xff09;为核心的广告交易方式。说到这里&#xff0c;你可能会有疑问&#xff1a;像百度搜索关键词广告还有百度网盟的广告&#xff0c;不也是CPC实时竞价的吗&#x…

创建kset

1、kset介绍 2、相关结构体和api介绍 2.1 struct kset 2.2 kset_create_and_add kset_create_and_addkset_createkset_registerkobject_add_internalkobject_add_internal2.3 kset_unregister kset_unregisterkobject_delkobject_put3、实验操作 #include<linux/module.…

kafka(一)原理(2)组件

一、broker 1、介绍 kafka服务器的官方名字&#xff0c;一个集群由多个broker组成&#xff0c;一个broker可以容纳多个topic。 2、工作流程 3、重要参数 参数名称 描述 replica.lag.time.max.ms ISR中&#xff0c;如果Follower长时间未向Leader发送通信请求或同步数据&a…

【分布式数据仓库Hive】HivQL的使用

目录 一、Hive的基本操作 1. 使用Hive创建数据库test 2. 检索数据库&#xff08;模糊查看&#xff09;&#xff0c;检索形如’te*’的数据库 3. 查看数据库test详情 4. 删除数据库test 5. 创建一个学生数据库Stus&#xff0c;在其中创建一个内部表Student&#xff0c;表格…

开源自动化热键映射工具autohotkey十大用法及精选脚本

AutoHotkey&#xff08;AHK&#xff09;是一款功能强大的热键脚本语言工具&#xff0c;它允许用户通过编写脚本来自动化键盘、鼠标等设备的操作&#xff0c;从而极大地提高工作效率。以下是AutoHotkey的十大经典用法&#xff0c;这些用法不仅解放了用户的双手&#xff0c;还展示…

OpenGL3.3_C++_Windows(27)

法线/凹凸贴图 如何让纹理产生更细节的效果&#xff0c;产生凹凸视觉感&#xff1f;解决思路之一&#xff1a;镜面贴图(黑—白&#xff09;&#xff08;&#xff08;diffuse贴图&#xff08;rgba&#xff09;&#xff09;&#xff0c;阻止部分表面被照的更亮&#xff0c;但这并…

不是大厂云用不起,而是五洛云更有性价比

明月代维的一个客户的大厂云境外云服务器再有几天就到期了&#xff0c;续费提醒那是提前一周准时到来&#xff0c;但是看到客户发来的续费价格截图&#xff0c;我是真的没忍住。这不就是在杀熟吗&#xff1f;就这配置续费竟然如此昂贵&#xff1f;说实话这个客户的服务器代维是…

ForkJoin框架与工作窃取算法详解

文章目录 一、ForkJoin框架概述1_核心概念2_主要类和方法1_ForkJoinPool2_ForkJoinTask 二、启用异步模式与否的区别三、ForkJoinPool的三种任务提交方式四、执行逻辑及使用示例1_示例&#xff1a;并行计算数组元素和2_forkJoinPool.submit3_ForkJoinTask<?>中任务的执行…

Web3 前端攻击:原因、影响及经验教训

DeFi的崛起引领了一个创新和金融自由的新时代。然而&#xff0c;这种快速增长也吸引了恶意行为者的注意&#xff0c;他们试图利用漏洞进行攻击。尽管很多焦点都集中在智能合约安全上&#xff0c;但前端攻击也正在成为一个重要的威胁向量。 前端攻击的剖析 理解攻击者利用前端漏…

uniapp标题水平对齐微信小程序胶囊按钮及适配

uniapp标题水平对齐微信小程序胶囊按钮及适配 状态栏高度胶囊按钮的信息计算顶部边距模板样式 标签加样式加动态计算实现效果 t是胶囊按钮距离的top h是胶囊按钮的高度 s是状态栏高度 大概是这样 状态栏高度 获取系统信息里的状态栏高度 const statusBarHeight uni.getSy…

使用CubeIDE调试项目现stm32 no source available for “main() at 0x800337c:

使用CubeIDE调试项目现stm32 no source available for "main() at 0x800337c&#xff1a; 问题描述 使用CubeIDE编译工程代码和下载都没有任何问题&#xff0c;点击Debug调试工程时&#xff0c;出现stm32 no source available for "main() at 0x800337c 原因分析&a…

数据结构与算法笔记:实战篇 - 剖析微服务接口鉴权限流背后的数据结构和算法

概述 微服务是最近几年才兴起的概念。简单点将&#xff0c;就是把复杂的大应用&#xff0c;解耦成几个小的应用 。这样做的好处有很多。比如&#xff0c;这样有利于团队组织架构的拆分&#xff0c;比较团队越大协作的难度越大&#xff1b;再比如&#xff0c;每个应用都可以独立…

nginx优化和防盗链

1、隐藏版本号 [roottest1 conf]# vim nginx.conf ​ server_tokens off; ​ 2、防盗链 修改用户和所在组 [roottest1 conf]# vim nginx.conf ​ #user nginx nginx; #表示主进程master会有root创建&#xff0c;子进程会有nginx用户来创建。 3、设置页面的缓存时间 主要是…

2024-2025年本田维修电路图线路图接线图资料更新

此次更新了2024-2025年本田车系电路图资料&#xff0c;覆盖市面上99%车型&#xff0c;包括维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等等&#xff01; 汽修帮手汽…

15- 22题聚合函数 - 高频 SQL 50 题基础版

目录 1. 相关知识点2. 例子2.15 - 有趣的电影2.16 - 平均售价2.17 - 项目员工 I2.18 - 各赛事的用户注册率2.19 - 查询结果的质量和占比2.20 - 每月交易 I2.21 - 即时食物配送 II2.22 - 游戏玩法分析 IV 1. 相关知识点 函数 函数含义order by排序group by分组between 小值 an…

Sping源码(九)—— Bean的初始化(非懒加载)—mergeBeanDefinitionPostProcessor

序言 前几篇文章详细介绍了Spring中实例化Bean的各种方式&#xff0c;其中包括采用FactoryBean的方式创建对象、使用反射创建对象、自定义BeanFactoryPostProcessor以及构造器方式创建对象。 创建对象 这里再来简单回顾一下对象的创建&#xff0c;不知道大家有没有这样一个疑…

边缘混合计算智慧矿山视频智能综合管理方案:矿山安全生产智能转型升级之路

一、智慧矿山方案介绍 智慧矿山是以矿山数字化、信息化为前提和基础&#xff0c;通过物联网、人工智能等技术进行主动感知、自动分析、快速处理&#xff0c;实现安全矿山、高效矿山的矿山智能化建设。旭帆科技TSINGSEE青犀基于图像的前端计算、边缘计算技术&#xff0c;结合煤…

【原创实现 设计模式】Spring+策略+模版+工厂模式去掉if-else,实现开闭原则,优雅扩展

1 定义与优点 1.1 定义 策略模式&#xff08;Strategy Pattern&#xff09;属于对象的⾏为模式。他主要是用于针对同一个抽象行为&#xff0c;在程序运行时根据客户端不同的参数或者上下文&#xff0c;动态的选择不同的具体实现方式&#xff0c;即类的行为可以在运行时更改。…

WIN32核心编程 - 数据类型 错误处理 字符处理

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 数据类型 基本数据类型 Win32基本数据类型 错误处理 C语言中的错误处理 C中的错误处理 Win32中的错误处理 字符处理 C/C WIN32 字符处理 数据类型 基本数据类型 C/C语言定义了一系列…