Threads in Java

2025年16月 | 阅读 7 分钟

在引入线程概念之前,我们无法同时运行多个任务。这是一个缺点,为了消除这个缺点,引入了线程概念

线程是一个非常轻量级的进程,或者我们可以说它是进程中允许程序通过同时运行多个任务来更有效地运行的最小部分。

为了在后台执行复杂的任务,我们使用了Java中的线程概念。所有任务的执行都不会影响主程序。在程序或进程中,所有线程都有自己的独立执行路径,因此进程的每个线程都是独立的。

Thread Concept in Java

使用线程的另一个好处是,如果线程在其执行过程中遇到异常或错误,它不会影响其他线程的执行。所有线程共享公共内存,并拥有自己的堆栈、局部变量和程序计数器。当多个线程在同一时间并行执行时,这个过程称为多线程

简单来说,线程是

  • 一种可以通过它在单个进程中执行多个活动的功能。
  • 轻量级进程。
  • 一系列执行的语句。
  • 嵌套调用的方法序列。

线程模型

Thread Concept in Java

就像进程一样,线程也有几种状态。这些状态如下:

  1. 新建(准备运行):当线程获得 CPU 时间时,它处于新建状态。
  2. 运行中:当线程正在执行时,它处于运行状态。
  3. 暂停:当线程暂时处于非活动状态或执行中时,它处于暂停状态。
  4. 阻塞:当线程等待资源时,它处于阻塞状态。
  5. 终止:当线程在任何给定时间立即停止执行时,它进入终止状态。

创建线程

线程的创建是通过“创建或实现”Runnable 接口或通过扩展Thread 类来完成的。这是创建线程的仅有的两种方式。

让我们深入了解创建线程的这两种方式的细节。

线程类

Thread 类有多种方法和构造函数,允许我们对线程执行各种操作。Thread 类继承自 Object 类。Object 类实现了 Runnable 接口。Thread 类具有用于执行各种操作的以下构造函数。

  • Thread()
  • Thread(Runnable, String name)
  • Thread(Runnable target)
  • Thread(ThreadGroup group, Runnable target, String name)
  • Thread(ThreadGroup group, Runnable target)
  • Thread(ThreadGroup group, String name)
  • Thread(ThreadGroup group, Runnable target, String name, long stackSize)

Runnable 接口(run() 方法)

需要由其实例将被线程执行的类来实现 Runnable 接口。Runnable 接口提供 run() 方法作为线程。

start() 方法

该方法用于启动新创建的线程。它启动一个具有新调用堆栈的新线程。执行 start() 方法后,线程的状态从新建变为可运行。当线程获得正确的时间来管理它时,它会执行 run() 方法

让我们以一个例子来了解如何通过扩展 Thread 类来创建 Java 线程。

示例

编译并运行

输出

The thread started running.
The sum of the two numbers is: 22

通过实现 Runnable 接口创建线程

在 Java 中,我们也可以通过实现 Runnable 接口来创建线程。Runnable 接口为我们提供了 run() 方法和 start() 方法。

让我们以一个例子来了解如何使用 Runnable 接口创建、启动和运行线程。

示例

编译并运行

输出

A New thread: Thread[#20,1st,5,main]is created
A New thread: Thread[#21,2nd,5,main]is created
A New thread: Thread[#22,3rd,5,main]is created

1st: 5
3rd: 5
2nd: 5
1st: 4
3rd: 4
2nd: 4
1st: 3
3rd: 3
2nd: 3
1st: 2
2nd: 2
3rd: 2
1st: 1
2nd: 1
3rd: 1
1st thread exiting.
3rd thread exiting.
2nd thread exiting.
We are exiting from Main Thread.

在上面的例子中,我们通过实现 Runnable 接口来实现多线程。

线程同步

在多线程环境中,同步对共享资源的访问至关重要,以防止数据损坏并确保一致性。Java 提供了同步机制,如 synchronized 关键字和 java.util.concurrent 包,以促进线程同步。

synchronized 关键字可用于创建同步方法或同步块。

或者,java.util.concurrent 包提供了更高级的并发实用工具,包括锁、信号量和原子变量,以更有效地管理线程同步。

线程池

单独创建和管理线程可能效率低下,尤其是在任务数量很多的应用程序中。线程池通过重用现有线程来执行多个任务来提供解决方案,从而降低了线程创建和销毁的开销。

Java 的 ExecutorService 和 ThreadPoolExecutor 类有助于创建和管理线程池。

线程优先级

Java 允许开发人员为线程分配优先级,这会影响 JVM 线程调度程序做出的调度决策。高优先级线程会获得调度程序的优先,但线程优先级仅是提示,而不是执行顺序的严格保证。

线程间通信

线程通常需要相互通信以协调其活动或交换数据。Java 提供了 wait()、notify() 和 notifyAll() 等方法,以及 synchronized 关键字,以促进线程间通信和同步。

守护线程

守护线程是低优先级的线程,它们在后台运行,为其他线程提供服务或执行垃圾回收等任务。当程序中所有非守护线程都执行完毕时,守护线程会自动终止。

线程安全

在多线程应用程序中确保线程安全至关重要,以防止竞用条件、数据损坏和其他并发相关问题。使用线程安全数据结构、采用同步和最小化共享可变状态等技术有助于实现线程安全。

线程中断

Java 提供了 interrupt() 方法来中断线程的执行,发出信号让它停止当前活动并优雅地终止。线程可以使用 isInterrupted() 方法检查其中断状态,或捕获 InterruptedException 以适当地处理中断。

线程局部变量

线程局部变量是每个线程都有自己独立副本的变量,确保每个线程访问其实例而不受其他线程的干扰。Java 的 ThreadLocal 类提供了一种方便的方式来创建和管理线程局部变量。

结论

在 Java 编程世界中,理解线程概念对于构建响应式、可伸缩且高效的应用程序至关重要。线程使开发人员能够通过并发执行多个任务来充分利用现代多核处理器的潜力。

通过掌握线程创建、生命周期管理、同步和线程池,Java 开发人员可以释放多线程的强大功能并开发高性能软件解决方案。

Java 线程概念 MCQ

1. 用于启动新创建线程的方法是?

  1. run()
  2. start()
  3. init()
  4. begin()
 

答案:B)

解释:start() 方法用于开始执行线程,该方法内部调用 run() 方法。


2. 通过实现 Runnable 接口创建线程必须实现哪个接口?

  1. Thread
  2. Runnable
  3. Callable
  4. Future
 

答案:B)

解释:必须实现 Runnable 接口才能通过定义 run() 方法来创建线程。


3. 在 Java 中,新创建线程的默认优先级是多少?

  1. 1
  2. 5
  3. 10
  4. 0
 

答案:B)

解释:新创建线程的默认优先级是 5 (NORM_PRIORITY)。


4. 用于将线程的执行暂停指定时间的方法是?

  1. wait()
  2. sleep()
  3. join()
  4. notify()
 

答案:B)

解释:sleep() 方法会将当前线程的执行暂停指定的时间。


5. 用于确保一段代码一次只有一个线程执行的关键字是?

  1. synchronized
  2. volatile
  3. static
  4. transient
 

答案:A)

解释:synchronized 关键字用于确保一次只有一个线程可以执行一段代码,从而提供线程安全。