Java线程面试指南二
系列文章导航
- Java 内存管理面试指南一
- Java 基础面试指南一
- Java 基础面试指南二
- Java 基础面试指南三
- Java 基础面试指南四
- Java 线程面试指南一
- Java 线程面试指南二
- Redis 面试指南一
- Kafka 面试指南一
- Spring 面试指南一
- SpringBoot 面试指南一
- 微服务面试指南一
什么是多线程?
多线程(Multithreading)是指同时执行多个线程的过程。Java 支持单线程以及多线程操作。单线程程序具有一个入口点(main() 方法)和一个出口点;而多线程程序具有一个初始入口点(main() 方法),其后是许多入口点和出口点,它们与 main() 方法同时运行。术语并发(Concurrency)是指同时执行多个任务。多处理和多线程都用于执行多任务。
它的主要优点是:
- 线程共享相同的地址空间。
- 线程是轻量级的。
- 线程之间的切换成本低。
用户线程和守护线程之间有什么区别?
当我们在 Java 程序中创建线程时,它被称为用户线程(User Thread)。守护线程(Daemon Thread)在后台运行,并且不会阻止 JVM 终止。当没有用户线程在运行时,JVM 会关闭程序并退出。从守护线程创建的子线程也是守护线程。
什么是多线程中的上下文切换?
上下文切换(Context Switch)是存储和恢复 CPU 状态的过程,以便可以在以后的某个时间点从同一点恢复线程执行。上下文切换是多任务操作系统的基本功能,并且支持多线程环境。
多线程编程的好处是什么?
在多线程编程中,多个线程同时执行可以提高性能。因为在某些线程正在等待获取某些资源的情况下,CPU 不会处于空闲状态。多个线程共享堆内存,因此最好创建多个线程来执行某些任务,而不要创建多个进程。例如,Servlet 的性能比 CGI 更好,因为 Servlet 支持多线程,但 CGI 不支持。
线程的生命周期有哪些不同状态?
当我们在 Java 程序中创建线程时,其状态为“新建”(New)。然后,我们启动将其状态更改为“可运行”(Runnable)的线程。线程调度程序负责将 CPU 分配给可运行线程池中的线程,并将其状态更改为“运行”(Running)。其他线程状态为“等待”(Waiting)、“阻塞”(Blocked)和“终止”(Dead/Terminated)。
Process 和 Thread 有什么区别?
进程(Process)是一个自包含的执行环境,可以将其视为程序或应用程序;而线程(Thread)是进程中执行的单个任务。Java 运行时环境作为单个进程运行,其中包含不同的类和程序作为进程。线程可以称为轻量级进程。线程需要较少的资源来创建并存在于进程中,线程共享进程资源。
抢占式调度和时间分片有什么区别?
- 抢占式调度:最高优先级的任务会一直执行,直到进入等待状态、终止状态或存在更高优先级的任务为止。
- 时间分片:任务将执行预定义的时间片,然后重新进入就绪任务池。然后,调度程序根据优先级和其他因素确定下一步应执行的任务。
是否可以启动一个线程两次?
不,不可能两次启动一个线程。如果这样做,它将引发异常(IllegalThreadStateException)。
我们可以调用 run() 方法而不是 start() 吗?
是的,但是它将不能用作线程,而可以用作普通对象,因此在线程之间不会进行上下文切换。直接调用 run() 方法只是在当前线程中执行普通方法调用。
我们如何在特定时间内暂停执行线程?
我们可以使用 Thread 类的 sleep() 方法将 Thread 的执行暂停一定时间。请注意,这不会在特定时间内停止线程的处理,一旦线程从睡眠中醒来,其状态将更改为可运行,并根据线程调度执行该线程。
什么是线程调度程序和时间切片?
- 线程调度程序:是一种操作系统服务,它将 CPU 时间分配给可用的可运行线程。创建并启动线程后,其执行取决于
Thread Scheduler的实现。 - 时间分片:是将可用 CPU 时间划分为可用可运行线程的过程。可以根据线程优先级为线程分配 CPU 时间,或者等待更长时间的线程将在获得 CPU 时间时获得更高的优先级。线程调度不能由 Java 控制,因此始终最好从应用程序本身控制线程调度。
线程如何相互通信?
当线程共享资源时,线程之间的通信对于协调其工作很重要。Object 类的 wait()、notify() 和 notifyAll() 方法允许线程就资源的锁定状态进行通信。
我们如何在 Java 中实现线程安全?
有几种方法可以在 Java 中实现线程安全:
- 同步(
synchronization) - 原子并发类(atomic concurrent classes)
- 实现并发 Lock 接口(
Lockinterface) - 使用
volatile关键字 - 使用不可变类(Immutable Classes)
- 使用线程安全类(Thread-safe Classes)
如何在 Java 中创建守护程序线程?
Thread 类 setDaemon(true) 可用于在 Java 中创建守护程序线程。我们需要在调用 start() 方法之前调用此方法,否则它将引发 IllegalThreadStateException。
什么是 ThreadLocal?
Java ThreadLocal 用于创建线程局部变量。我们知道对象的所有线程都共享它的变量,因此,如果变量不是线程安全的,则可以使用同步,但是如果要避免同步,则可以使用 ThreadLocal 变量。
每个线程都有自己的 ThreadLocal 变量,他们可以使用它的 get() 和 set() 方法获取默认值或将其本地值更改为当前线程。ThreadLocal 实例通常是希望将状态与线程关联的类中的私有静态字段。
什么是 Java Thread Dump,我们如何获取程序的 Java Thread Dump?
Thread Dump 是 JVM 中所有活动线程的列表,Thread Dump 对于分析应用程序中的瓶颈和分析死锁情况非常有帮助。我们可以使用多种方法来 Dump Thread:
- 使用 Profiler
- 使用
kill -3命令 - 使用
jstack工具等
我更喜欢使用 jstack 工具来进行 Dump Thread,因为它易于使用并且随 JDK 安装一起提供。由于它是基于终端的工具,因此我们可以创建脚本以定期 Dump Thread,以供日后分析。
什么是线程池?我们如何在 Java 中创建线程池?
线程池管理工作线程池;它包含一个使任务等待执行的队列。线程池管理可运行线程的集合,工作线程从队列中执行可运行线程。
java.util.concurrent.Executors 提供 java.util.concurrent.Executor 接口的实现,以在 Java 中创建线程池。线程池示例程序显示了如何在 Java 中创建和使用线程池。或阅读 ScheduledThreadPoolExecutor 示例以了解如何在特定延迟后安排任务。
什么是同步?
同步(Synchronization)是控制多个线程对任何共享资源的访问的能力。它用于:
- 为了防止线程干扰。
- 以防止一致性问题。
同步块的目的是什么?
- 同步块用于锁定任何共享资源的对象。
- 同步块的范围小于该方法。
什么是静态同步?
如果将任何静态方法设置为已同步,则锁定将锁定在类上而不是对象上。
说明:本文内容基于 Java 多线程基础概念整理,适用于 Java 5 及以上版本(涉及 java.util.concurrent 包特性)。部分术语(如线程状态)在不同 Java 版本中可能存在细微差异,实际开发中请以官方文档为准。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/java-xian-cheng-mian-shi-zhi-nan-er.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。