Java 面试必问!线程构造方法和静态块的执行线程到底是谁?

开发 前端
你需要了解不同的线程同步技术,比如使用 synchronized 关键字,使用 ReentrantLock,以及 Java 中的原子类(如 AtomicInteger、AtomicReference 等)来保证线程安全。

引言

大家好!我是小米,今天我们来聊一聊一个关于 Java 多线程的社招面试题,相信对于很多 Java 开发者来说,这个问题肯定不陌生——线程类的构造方法、静态块是被哪个线程调用的?

这听起来好像是一个很基础的知识点,但是如果你不是特别了解 Java 的多线程机制,或者你刚接触过多线程编程,那这个问题背后的机制和细节就可能会让你陷入困惑。别急,我来给大家详细讲解,带大家走一遍完整的分析过程。

问题:线程类的构造方法、静态块是被哪个线程调用的?

这个问题的核心就是想让你理解 Java 中线程的生命周期,特别是对于 Thread 类、Runnable 接口的实现,以及线程的启动过程。在这个过程中,线程的构造方法和静态块到底是在哪个线程中被调用的,这个问题看似简单,却涉及到很多背后的细节。

线程类的构造方法到底是哪个线程调用的?

首先,我们从一个简单的案例入手,假设我们有一个自定义的线程类:

图片图片

看上去非常简单,对吧?如果我们创建一个 MyThread 的实例,并调用 start() 方法来启动线程:

图片图片

接下来,问题来了,线程的构造方法究竟是哪个线程调用的呢?

答案是:构造方法是由主线程(即当前执行 main 方法的线程)来调用的。

为什么是主线程?

这是因为我们在主线程中创建了 MyThread 类的实例。无论你创建多少个线程,线程的构造方法本身是在当前线程中执行的,即在 new MyThread() 这一行代码执行时,构造方法就是在当前线程(此时是主线程)中被调用。

虽然我们之后通过调用 thread.start() 启动了新的线程,但是这个启动过程本身是由主线程来发起的。所以,在此之前的构造过程,线程的构造方法自然是由主线程来执行。

线程的静态块到底是由哪个线程调用的?

静态块的调用时机是类加载时。如果我们再来看一个简单的代码示例:

图片图片

在这个代码中,我们加了一个静态块,静态块的作用是当类加载到 JVM 中时自动执行。那么,问题来了:静态块到底是由哪个线程调用的呢?

答案是:静态块是在类加载时由主线程调用的。

具体来说,静态块的执行是在类加载器加载类的过程中进行的,而类加载本身是在主线程中进行的。因此,不管后面我们创建了多少线程,静态块的执行都在主线程中完成。

再看看线程的启动过程

接下来,我们再深入一步,来看看线程是如何启动的。

在我们调用 thread.start() 启动线程时,实际上执行的是 Thread 类的 start() 方法。具体流程如下:

  • Thread.start() 方法会执行一些线程启动前的准备工作。
  • 然后,它会调用 Thread.run() 方法,启动线程。

但是,这并不是线程的执行过程。线程的 run() 方法是在 线程自身 中执行的,而不是在调用 start() 方法的线程中。

这就意味着,调用 start() 方法的线程是主线程,但 run() 方法的执行是由新的线程来执行的。

小结一下:谁在调用构造方法和静态块?

  • 构造方法: 线程类的构造方法是由当前线程调用的,通常是主线程。即使你新创建了线程实例,线程构造方法本身也是在主线程中执行的。
  • 静态块: 静态块是在类加载的时候执行的,而类加载通常是由主线程来完成的,因此静态块是在主线程中被调用的。

相关知识点拓展

既然聊到线程的构造方法和静态块,我们可以进一步了解一下线程启动的全过程,以便更加深入理解其中的细节。

线程的生命周期

线程的生命周期有几个关键的状态:新建状态(New)、可运行状态(Runnable)、阻塞状态(Blocked)、等待状态(Waiting)、终止状态(Terminated)。不同状态之间的转换由 JVM 和操作系统控制,作为开发者,我们只需要关心线程的创建、启动和销毁。

线程的启动过程

线程的启动其实就是调用了 Thread.start() 方法,而 Thread.start() 方法会最终调用 run() 方法。如果你自己没有重写 run() 方法,JVM 会调用 Thread 类的 run() 方法,但如果你重写了 run() 方法,那么 run() 方法会在新线程中执行。

线程池和线程复用

在实际开发中,创建和销毁线程是非常耗费资源的,特别是当线程频繁创建和销毁时,会严重影响性能。为了优化这个问题,我们通常会使用线程池。线程池可以复用线程,减少线程的创建和销毁带来的开销。

面试题实战:如何避免线程安全问题?

面试中不仅仅是考察这些基础的知识点,还可能会涉及到线程安全问题的相关考察。常见的面试题包括:

  • 如何保证线程安全?
  • 什么是死锁?如何避免死锁?
  • 如何实现线程同步?
  • 什么是原子操作?

对于这些问题,你需要了解不同的线程同步技术,比如使用 synchronized 关键字,使用 ReentrantLock,以及 Java 中的原子类(如 AtomicInteger、AtomicReference 等)来保证线程安全。

总结

今天的文章我们通过一个简单的 Java 面试题,详细地讲解了线程类的构造方法和静态块是由哪个线程调用的。可以看出,虽然这个问题看起来简单,但背后隐藏着 Java 多线程机制的一些细节,理解这些细节对于我们掌握 Java 多线程编程非常重要。

如果你在面试中遇到类似的问题,记得仔细分析线程的生命周期以及不同线程操作之间的关系。通过实际编写代码,实践并理解这些机制,才能在面试中游刃有余地回答出这个问题。

责任编辑:武晓燕 来源: 软件求生
相关推荐

2024-11-07 12:37:17

2020-10-12 18:00:39

JavaAQS代码

2023-08-15 15:33:29

线程池线程数

2022-01-28 00:00:42

高并发线程顺序

2020-02-18 14:25:51

Java线程池拒绝策略

2024-05-11 09:41:45

线程安全代码

2020-12-28 08:18:55

安全代码线程

2020-08-19 07:48:11

云计算亚马逊搜索

2020-06-02 10:38:15

IDEiOSLinux

2018-07-30 11:27:12

云服务

2021-12-09 12:22:28

MyBatis流程面试

2015-12-28 16:09:20

物联网市场

2012-08-16 09:15:29

2018-03-15 10:25:06

2017-04-19 12:36:53

2021-02-05 12:34:33

线程池系统

2023-02-03 07:24:49

双亲委派模型

2020-07-30 13:22:19

语言Android大数据

2018-09-10 16:23:36

手机信号信号差信号强度

2024-05-20 13:13:01

线程安全Java
点赞
收藏

51CTO技术栈公众号