38道多线程核心面试题(附答案)

前言

今天给大家分享的是比较全面的多线程面试题,大家在面试的过程中不免会被问到很多专业性的问题,有的时候回答的并不是那么全面和精细,这仅仅代表个人观点。

1. 如何预防死锁?

1.首先需要将死锁发生的是个必要条件讲出来

互斥条件 同一时间只能有一个线程获取资源。

不可剥夺条件 一个线程已经占有的资源,在释放之前不会被其它线程抢占

请求和保持条件 线程等待过程中不会释放已占有的资源

循环等待条件 多个线程互相等待对方释放资源

2.死锁预防,那么就是需要破坏这四个必要条件:

由于资源互斥是资源使用的固有特性,无法改变,我们不讨论

破坏不可剥夺条件

一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式地释放重新加入到系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行

破坏请求与保持条件

第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源,

第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源

破坏循环等待条件

采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少地采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。

2. 多线程有哪几种创建方式?

实现Runnable,Runnable规定的方法是run(),无返回值,无法抛出异常

实现Callable,Callable规定的方法是call(),任务执行后有返回值,可以抛出异常

继承Thread类创建多线程:继承java.lang.Thread类,重写Thread类的run()方法,在run()方法中实现运行在线程上的代码,调用start()方法开启线程。

Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法

通过线程池创建线程. 线程和数据库连接这些资源都是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。

3. 描述一下线程安全活跃态问题,竞态条件?

线程安全的活跃性问题可以分为 死锁、活锁、饥饿

1.活锁 就是有时线程虽然没有发生阻塞,但是仍然会存在执行不下去的情况,活锁不会阻塞线程,线程会一直重复执行某个相同的操作,并且一直失败重试

我们开发中使用的异步消息队列就有可能造成活锁的问题,在消息队列的消费端如果没有正确的ack消息,并且执行过程中报错了,就会再次放回消息头,然后再拿出来执行,一直循环往复的失败。这个问题除了正确的ack之外,往往是通过将失败的消息放入到延时队列中,等到一定的延时再进行重试来解决。

解决活锁的方案很简单,尝试等待一个随机的时间就可以,会按时间轮去重试

2.饥饿 就是 线程因无法访问所需资源而无法执行下去的情况,

饥饿分为两种情况:

一种是其他的线程在临界区做了无限循环或无限制等待资源的操作,让其他的线程一直不能拿到锁进入临界区,对其他线程来说,就进入了饥饿状态

另一种是因为线程优先级不合理的分配,导致部分线程始终无法获取到CPU资源而一直无法执行

3.解决饥饿的问题有几种方案:

保证资源充足,很多场景下,资源的稀缺性无法解决

公平分配资源,在并发编程里使用公平锁,例如FIFO策略,线程等待是有顺序的,排在等待队列前面的线程会优先获得资源

避免持有锁的线程长时间执行,很多场景下,持有锁的线程的执行时间也很难缩短

4.死锁 线程在对同一把锁进行竞争的时候,未抢占到锁的线程会等待持有锁的线程释放锁后继续抢占,如果两个或两个以上的线程互相持有对方将要抢占的锁,互相等待对方先行释放锁就会进入到一个循环等待的过程,这个过程就叫做死锁

线程安全的竞态条件问题

同一个程序多线程访问同一个资源,如果对资源的访问顺序敏感,就称存在竞态条件,代码区成为临界区。 大多数并发错误一样,竞态条件不总是会产生问题,还需要不恰当的执行时序

最常见的竞态条件为

先检测后执行执行依赖于检测的结果,而检测结果依赖于多个线程的执行时序,而多个线程的执行时序通常情况下是不固定不可判断的,从而导致执行结果出现各种问题,见一种可能 的解决办法就是:在一个线程修改访问一个状态时,要防止其他线程访问修改,也就是加锁机制,保证原子性

延迟初始化(典型为单例)

4. Java中的wait和sleep的区别与联系?

1.所属类: 首先,这两个方法来自不同的类分别是Thread和Object ,wait是Object的方法,sleep是Thread的方法

sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码

2.作用范围: sleep方法没有释放锁,只是休眠,而wait释放了锁,使得其他线程可以使用同步控制块或方法

3.使用范围: wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用

4.异常范围: sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

5. 描述一下进程与线程区别?

1.进程(Process)

是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。总结: j进程是指在系统中正在运行的一个应用程序;程序一旦运行就是进程;进程——资源分配的最小单位

2.线程

操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。总结: 系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。线程——程序执行的最小单位

6. 描述一下Java线程的生命周期?

大致包括5个阶段

新建 就是刚使用new方法,new出来的线程;

就绪 就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;

运行 当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;

阻塞 在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;

销毁 如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源

1.按JDK的源码分析来看,Thread的状态分为:

NEW: 尚未启动的线程的线程状态

RUNNABLE: 处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统(例如处理器)的其他资源

BLOCKED: 线程的线程状态被阻塞,等待监视器锁定。处于阻塞状态的线程正在等待监视器锁定以输入同步的块方法或在调用后重新输入同步的块方法,通过 Object#wait()进入阻塞

WAITING:处于等待状态的线程正在等待另一个线程执行特定操作:例如: 在对象上调用了Object.wait()的线程正在等待另一个线程调用Object.notify() 或者Object.notifyAll(), 调用了 Thread.join()的线程正在等待指定的线程终止

TIMED_WAITING : 具有指定等待时间的等待线程的线程状态。由于以指定的正等待时间调用以下方法之一,因此线程处于定时等待状态:

Thread.sleep(long)

Object#wait(long)

Thread.join(long)

LockSupport.parkNanos(long…)

LockSupport.parkUntil(long…)

2.TERMINATED: 终止线程的线程状态。线程已完成执行

7. 程序开多少线程合适?

1.这里需要区别下应用是什么样的程序:

CPU 密集型程序,一个完整请求,I/O操作可以在很短时间内完成, C

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
多选题: 1. 电池PACK是由以下哪些组件组成? A. 电池单体 B. 控制器 C. 散热器 D. 电机 答案:A、B、C 2. 电池PACK的额定电压是多少? A. 12V B. 24V C. 48V D. 96V 答案:B、C、D 3. 电池PACK的容量指的是什么? A. 电池的电压 B. 电池的电流 C. 电池的储存能量 D. 电池的输出功率 答案:C 4. 电池PACK的充电方式有哪些? A. 直流充电 B. 交流充电 C. 快速充电 D. 慢速充电 答案:A、B、C、D 5. 电池PACK的放电方式有哪些? A. 直流放电 B. 交流放电 C. 快速放电 D. 慢速放电 答案:A、B 6. 电池PACK的保护措施有哪些? A. 过充保护 B. 过放保护 C. 短路保护 D. 过流保护 答案:A、B、C、D 7. 电池PACK的寿命受到哪些因素的影响? A. 温度 B. 充放电次数 C. 充放电速度 D. 储存时间 答案:A、B、C、D 8. 电池PACK的维护工作包括哪些? A. 清理电池表面 B. 定期充电 C. 更换故障单体 D. 调整电池输出功率 答案:A、B、C 9. 电池PACK的故障可能会导致什么后果? A. 减少电池寿命 B. 增加车辆能耗 C. 减少车辆续航里程 D. 危及车辆安全 答案:A、B、C、D 10. 电池PACK的重要性体现在哪些方面? A. 能源效率 B. 环保性 C. 车辆性能 D. 能源安全 答案:A、B、C、D 填空题: 1. 电池PACK由多个 __电池单体__ 组成。 2. 电池PACK的容量以 __安时(Ah)__ 为单位。 3. 电池PACK的充电时间长短取决于充电器的 __功率__。 4. 电池PACK的寿命与充放电次数、充放电速度、储存时间和 __温度__ 相关。 5. 电池PACK的故障可能会导致车辆续航里程 __减少__。 6. 电池PACK的维护工作包括清理电池表面、定期充电和更换故障 __电池单体__。 7. 电池PACK的重要性体现在能源效率、环保性、车辆性能和能源 __安全__。 8. 电池PACK的保护措施包括过充保护、过放保护、短路保护和 __过流保护__。 9. 电池PACK的充电方式包括直流充电和 __交流充电__。 10. 电池PACK的额定电压通常为 __24V__、__48V__ 或 __96V__。 答案: 1. 电池单体 2. 安时(Ah) 3. 功率 4. 温度 5. 减少 6. 电池单体 7. 安全 8. 过流保护 9. 交流充电 10. 24V、48V 或 96V
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DN金猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值