多线程的常见面试题

简介: 目录前言1. 什么是线程2. 并发与并行3. 线程死锁4. sleep和wait方法5. 调用start()执行run(),为何不是直接调用run()6. synchronized 关键字的了解7. 线程池8. 执⾏execute()方法和 submit()方法的区别前言主要描述线程的一些相关概念和易混淆的知识点这部分内容也是面试官经常爱问的问题具体这部分的详细知识可看我之前的文章【操作系统】线程与进程的深入剖析(全)【操作系统】守护线程和守护进程的区别JUC高并发编程从入门到精通(全)

前言

主要描述线程的一些相关概念和易混淆的知识点
这部分内容也是面试官经常爱问的问题

具体这部分的详细知识可看我之前的文章

  1. 【操作系统】线程与进程的深入剖析(全)
  2. 【操作系统】守护线程和守护进程的区别
  3. JUC高并发编程从入门到精通(全)

以及这篇操作系统的相关面试题
【操作系统】常见面试题集锦(全)

1. 什么是线程

线程是⼀个⽐进程更⼩的执⾏单位。⼀个进程在其执⾏的过程中可以产⽣多个线程,与进程不同的是同类的多个线程共享进程的堆和⽅法区资源,但每个线程有⾃⼰的==程序计数器、虚拟机栈和本地⽅法栈==

补充:

  • 程序计数器私有主要是为了线程切换后能恢复到正确的执⾏位置
  • jvm栈和本地方法栈私有是为了保证线程中的局部变量不被别的线程访问到

2. 并发与并行

  • 并发: 同⼀时间段,多个任务都在执⾏ (单位时间内不⼀定同时执⾏);
  • 并⾏: 单位时间内,多个任务同时执⾏

3. 线程死锁

多个线程同时被阻塞,它们中的⼀个或者全部都在等待某个资源被释放。由于线程被⽆限期地阻塞,因此程序不可能正常终⽌

产生死锁的四个必要条件:

  1. 互斥条件:该资源任意⼀个时刻只由⼀个线程占⽤。
  2. 请求与保持条件:⼀个进程因请求资源⽽阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:线程已获得的资源在末使⽤完之前不能被其他线程强⾏剥夺,只有⾃⼰使⽤完毕后才释放资源。
  4. 循环等待条件:若⼲进程之间形成⼀种头尾相接的循环等待资源关系

避免线程死锁:

  1. 破坏互斥条件 :这个条件我们没有办法破坏,因为我们⽤锁本来就是想让他们互斥的(临界资源需要互斥访问)。
  2. 破坏请求与保持条件 :⼀次性申请所有的资源。
  3. 破坏不剥夺条件 :占⽤部分资源的线程进⼀步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
  4. 破坏循环等待条件 :靠按序申请资源来预防。按某⼀顺序申请资源,释放资源则反序释放。破坏循环等待条件

4. sleep和wait方法

区别 wait sleep
不同点 Object 的方法,会释放锁,调用它的前提是当前线程占有锁(即代码要在 synchronized 中) Thread 的静态方法,任何对象实例都能调用。不会释放锁,也不需要占用锁
相同点 都可以被 interrupted 方法中断 都可以被 interrupted 方法中断
  • sleep() ⽅法没有释放锁,⽽ wait() ⽅法释放了锁
  • wait() ⽅法被调⽤后,线程不会⾃动苏醒,需要别的线程调⽤同⼀个对象上的 notify() 或 者 notifyAll() ⽅法。

sleep() ⽅法执⾏完成后,线程会⾃动苏醒

5. 调用start()执行run(),为何不是直接调用run()

详情可看我这篇文章
多线程中run()和start()的异同详细分析(全)

直接执⾏ run() ⽅法,会把 run()⽅法当成⼀个 main 线程下的普通⽅法去执⾏,并不会在某个线程中执⾏它,所以这并不是多线程⼯作

6. synchronized 关键字的了解

详情可看我这篇文章
java并发之synchronized详细分析(全)

以保证被它修饰的⽅法或者代码块在任意时刻只能有⼀个线程执⾏。

  • synchronized 关键字加到 static 静态⽅法和 synchronized(class) 代码块上都是是给 Class类上锁。
  • synchronized 关键字加到实例⽅法上是给对象实例上锁。

7. 线程池

想主要是为了减少每次获取资源的消耗,提⾼对资源的利⽤率

  • 降低资源消耗。通过重复利⽤已创建的线程降低线程创建和销毁造成的消耗。
  • 提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。
  • 提⾼线程的可管理性。线程是稀缺资源,如果⽆限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使⽤线程池可以进⾏统⼀的分配,调优和监控

8. 执⾏execute()方法和 submit()方法的区别

  1. execute() ⽅法⽤于提交不需要返回值的任务,所以⽆法判断任务是否被线程池执⾏成功与否;
  2. submit() ⽅法⽤于提交需要返回值的任务。线程池会返回⼀个 Future 类型的对象,通过这个 Future 对象可以判断任务是否执⾏成功,并且可以通过 Future 的 get() ⽅法来获取返回值, get() ⽅法会阻塞当前线程直到任务完成

9. 线程的三种创建方式

可看我之前的这篇文章
java线程的三种创建方式详细分析(全)

10. 线程池的四种创建方式

可看我之前的这篇文章
java线程池的四种创建方式详细分析(全)

相关文章
|
25天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
44 1
|
1月前
|
安全 Java
Qt经典面试题:Qt开启线程的几种方式
Qt经典面试题:Qt开启线程的几种方式
22 0
|
1月前
|
并行计算 安全 Java
C# .NET面试系列四:多线程
<h2>多线程 #### 1. 根据线程安全的相关知识,分析以下代码,当调用 test 方法时 i > 10 时是否会引起死锁? 并简要说明理由。 ```c# public void test(int i) { lock(this) { if (i > 10) { i--; test(i); } } } ``` 在给定的代码中,不会发生死锁。死锁通常是由于两个或多个线程互相等待对方释放锁而无法继续执行的情况。在这个代码中,只有一个线程持有锁,且没有其他线程参与,因此不
104 3
|
3月前
|
Java 调度 Windows
JAVA面试八股文之多线程基础知识
JAVA面试八股文之多线程基础知识
|
3月前
|
调度
【面试问题】说说线程的生命周期?
【1月更文挑战第27天】【面试问题】说说线程的生命周期?
|
6天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
22 0
|
1月前
|
消息中间件 存储 算法
【C/C++ 泡沫精选面试题04】在实际项目中,多进程和多线程如何选择?
【C/C++ 泡沫精选面试题04】在实际项目中,多进程和多线程如何选择?
43 1
|
1月前
|
消息中间件 算法 开发者
【Qt面试题】多线程情况下, Qt中的信号槽分别在什么线程中执行, 如何控制?
【Qt面试题】多线程情况下, Qt中的信号槽分别在什么线程中执行, 如何控制?
19 1
|
1月前
|
Java 调度
金三银四面试必问:线程有几种状态
金三银四面试必问:线程有几种状态
14 0
|
2月前
|
Java API 开发者
高逼格面试:线程封闭,新名词√
高逼格面试:线程封闭,新名词√
33 0

热门文章

最新文章