面试题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.mzph.cn/pingmian/39794.shtml

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

相关文章

用Chromatix进行tuning流程

##一、基本调试 ###1、工程初始配置&#xff1a; 这个工具就是一个图形化的参数编辑器&#xff0c;其实所有tuning中的效果参数直接改文件参数酒醒&#xff0c;工具的好处是&#xff1a;带有检查错误和模拟的功能以及一些校验工具和脚本。 初始化可以中需要的配置&#xff1a;t…

鸿蒙如何打包应用程序

总结鸿蒙应用程序包 之前文章详细讲解了关于三种程序包的内容&#xff0c;现在简单总结一下&#xff1a; 1. 总结 首先需要搞清楚鸿蒙项目的模块Module的分类: Module分为“Ability”和“Library”两种类型 HAP HAP: Harmony Ability Package , 叫做鸿蒙Ability包。 “Abil…

全面详解菲律宾slots游戏本土网盟广告CPI流量效果分析

全面详解菲律宾slots游戏本土网盟广告CPI流量效果分析 一、引言 随着互联网的普及和移动设备的广泛应用&#xff0c;网络游戏行业迅速崛起&#xff0c;成为全球娱乐市场的一大热门。菲律宾作为东南亚地区的重要国家&#xff0c;其网络游戏市场也呈现出蓬勃的发展势头。在这样的…

JavaScript中location对象的主要属性和方法

属性 href&#xff1a;获取或设置整个URL。protocol&#xff1a;获取URL的协议部分&#xff0c;如"http:"或"https:"。host&#xff1a;获取URL的主机名&#xff08;包括端口号&#xff0c;如果有的话&#xff09;。hostname&#xff1a;获取URL的主机名&…

Java中的并发容器:ConcurrentHashMap详解

Java中的并发容器&#xff1a;ConcurrentHashMap详解 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在多线程编程中&#xff0c;安全地访问和操作共享数据是一项关键任务。Java提供了一些并发容器…

电工电子革新风暴:在线电路仿真软件重塑行业格局

随着科技的不断进步&#xff0c;电工电子行业正迎来一场由在线电路仿真软件引领的革新风暴。这些功能强大的软件工具不仅极大地提高了电路设计的效率&#xff0c;更为整个行业带来了前所未有的冲击和机遇。 仿真软件&#xff1a;电工电子行业的“隐形推手” 在线电路仿真软件…

k8s_集群搭建_在主节点中加入node节点_k8s集群自恢复能力演示_token过期重新生成令牌---分布式云原生部署架构搭建016

然后安装好了master节点以后,我们再来看如何把node节点加入进来,可以看到 只需要执行,命令行中提示的命令就可以了 比如上面的 Your Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:…

非参数与半参数估计模型及 Stata 具体操作步骤

目录 一、引言 二、非参数与半参数估计模型的理论原理 非参数估计 半参数估计 三、数据 四、核密度估计的 Stata 操作 五、局部多项式回归的 Stata 操作 六、部分线性模型的 Stata 操作 七、总结 一、引言 在当今复杂多变的数据环境中&#xff0c;传统的基于严格参数假…

基于Java的音乐网站系统01239

目 录 摘要 1 绪论 1.1 研究背景 1.2系统开发目标、意义 1.3研究内容 2 相关技术介绍 2.1 MySQL数据库 2.2 Java编程语言 2.3 SpringBoot框架介绍 3 系统需求分析与设计 3.1 可行性分析 3.1.1 技术可行性分析 3.1.2 经济可行性分析 3.1.3 法律可行性分析 3.2 需…

从0开始搭建vue项目

#先查下电脑有没有安装过node和npm node -v npm -v #安装vue npm install -g vue #安装webpack npm install webpack -g 都安装好后&#xff0c;进入你想创建的文件夹内 创建名字&#xff1a;vue init webpack <project_name> 就默认回车 然后根据项目需求Y/n 比如…

使用Python下载并合并HLS视频片段

下载和合并视频片段的实用方法 在日常工作中&#xff0c;我们经常会遇到需要从网上下载视频并将其合并成一个完整视频的需求。本文将介绍如何使用 Python 下载多个视频片段&#xff0c;并使用 ffmpeg 将这些片段合并成一个完整的视频文件。以下是具体步骤和代码实现。 完整代…

超详细:安装Linux系统、虚拟现实教程

文章目录 一、如何下载并使用VMware虚拟机1.百度搜索vmware2.进入官网点击Workstation Pro链接3.博通注册对应的账号4.博通填写用户名、密码后直接登录会跳转到博通登录页5.个人使用选择个人版 二、国内镜像网站下载&#xff08;Centos版本&#xff09;三、镜像系统的安装1.打开…

网页打开摄像头录制视频,下载和上传,支持手机端

直接复制就可以用&#xff0c;上传自己改路径 <!DOCTYPE html> <html><head><title>video recoder</title><meta http-equiv"Content-Type" content"text/html; charsetUTF-8" /><meta charset"utf-8"…

无人机之运动状态篇

悬停 悬停状态是四旋无人机具有的一个显著特点。在悬停状态下&#xff0c;四个旋翼具有相等的转速&#xff0c;产生的上升合力正好与自身重力相等&#xff0c;并且因为旋翼转速大小相等&#xff0c;前后端转速方向相反&#xff0c;从而使得飞行器总扭矩为0&#xff0c;使得飞行…

揭秘!电路仿真软件为何成为老师教学新宠?

在数字化浪潮席卷全球的背景下&#xff0c;教育领域也迎来了前所未有的变革。近年来&#xff0c;电路仿真软件在教学中的应用越来越广泛&#xff0c;受到了老师们的热烈追捧。那么&#xff0c;究竟是什么让老师们对电路仿真软件情有独钟呢&#xff1f;今天&#xff0c;就让我们…

nginx的vim nginx.conf配置文件内容详解及实验,nginx的优化和防盗链

一、nginx网络服务器&#xff1a; 1. nginx是开源的&#xff0c;是一款高性能&#xff0c;轻量级的web服务软件&#xff1b;稳定性高&#xff0c;而且版本迭代比较快&#xff1b;修复bug速度比较快&#xff0c;安全性高&#xff1b;消耗资源低&#xff0c;http的请求并发连接&…

探索指针(4)-C语言

目录 1.回调函数 一.回调函数的基本概念 二.示例 三.详细说明 2.qsort使用举例 一.qsort 函数原型 二.参数解释 三.比较函数 3.qsort函数的模拟实现 一.代码示例&#xff1a; 二.分段讲解代码 1.回调函数 一.回调函数的基本概念 回调函数本质上是一种通过函数指…

将堆内存的最小值(Xms)与最大值(Xmx)设置为相同的配置,可以防止JVM在运行过程中根据需要动态调整堆内存大小

将堆内存的最小值&#xff08;Xms&#xff09;与最大值&#xff08;Xmx&#xff09;设置为相同的配置&#xff0c;可以防止JVM在运行过程中根据需要动态调整堆内存大小&#xff0c;从而避免因内存分配策略变化引起的性能波动&#xff0c;也就是所谓的"内存震荡"&…

RH442 开放研究实验: 选择性能监控工具

开放研究实验: 选择性能监控工具 任务执行清单 在本实验中&#xff0c;您将使用各种系统监控工具来观察系统表现。 成果 您应能够&#xff1a; 安装和配置 sysstat 软件包&#xff0c;以生成系统活动报告。安装和配置 Performance Co-Pilot&#xff0c;以采集原始数据来监…

流量攻击是什么意思?

对于多数的互联网企业都会受到流量攻击&#xff0c;那流量攻击是什么意思呢&#xff1f; 流量攻击一般是利用合理的服务请求来占用过多的服务器资源&#xff0c;从而导致正常合法的用户请求没有办法得到服务的响应&#xff0c;使服务无法进行正常的工作运行&#xff0c;流量攻击…