Java 多线程基础概念

x33g5p2x  于2021-12-18 转载在 其他  
字(1.9k)|赞(0)|评价(0)|浏览(376)

什么是进程?

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的,系统运行一个程序即是一个进程从创建、运行到消亡的过程。

什么是线程?

线程与进程类似,但线程是一个比进程更小的执行单元,一个进程在执行过程中可以产生多个线程,线程是操作系统调度的最小单元。

在 Java 中,同一进程的多个线程共享该进程的堆和方法区资源,但每个线程都有自己独立的程序计数器、虚拟机栈和本地方法栈,所以系统在线程之间切换工作的负担要比进程小,因此线程也被叫做轻量级进程。

Java 从诞生之初就支持多线程,所以 Java 程序天生就是多线程程序,我们可以通过 JMX 来查看一个普通的 Java 程序都包含哪些线程,代码如下。

public class MultiThread {
    public static void main(String[] args) {
        // 获取 Java 线程管理 MXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        // 不需要获取同步的 monitor 和 synchronizer 信息,仅获取线程和线程堆栈信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        // 遍历线程信息,仅打印线程 ID 和线程名称信息
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
        }
    }
}

输出如下所示(输出内容可能不相同)。

[6] Monitor Ctrl-Break	
[5] Attach Listener		
[4] Signal Dispatcher	// 分发处理发送给 JVM 信号的线程
[3] Finalizer			// 调用对象 finalize 方法的线程
[2] Reference Handler	// 清除 Reference 的线程
[1] main				// main 线程,程序入口

从输出结果可以看到,一个 Java 程序的运行不仅仅是 main() 方法的运行,而是 main 线程和多个其他线程的同时运行。

什么是守护线程?

在 Java 中线程分为两种:一种是用户线程,也称为非守护线程,上文中提到的 main 线程就是一个非守护线程;另一种是守护线程。

守护线程是一种特殊的线程,当进程中不存在非守护线程的时候,守护线程就会自动销毁。例如,垃圾回收线程就是一个典型的守护线程,当进程中已经不存在非守护线程的时候,垃圾回收线程也就没有存在的必要了,会自动销毁。当最后一个非守护线程销毁后,所有的守护线程也会自动销毁,进程也就随之结束了。

在 Java 中可以通过调用 setDaemon(boolean on) 方法并传入 true 值把非守护线程设置为守护线程。

并发和并行的区别?

并发是指在一段时间内多个任务都在执行,但在同一时刻没有同时执行。单核 CPU 在同一时刻只能执行一个任务,操作系统会为每个任务分配时间片,当时间片结束后当前任务无论完成与否都会停下来,把 CPU 让给其他任务来使用,由于 CPU 的计算速度非常快,所以在一段时间内这些任务看起来像是在“同时”运行,这些任务之间就是并发关系。

并行是指在同一时刻,多个任务同时执行。多核 CPU 在同一时刻可以执行多个任务,这些任务之间就是并行关系。

下图很形象地表明了并发和并行的区别:并发是两个队伍交替使用一台咖啡机;并行是两个队伍同时使用两台咖啡机。

为什么要使用多线程?

  1. 更多的处理器核心
    现在的 CPU 大多都是多核 CPU,一个单线程程序在同一时刻只能运行的一个处理器核心上,此时其他处理器核心则处于闲置状态,而如果使用多线程技术,将计算逻辑分配到多个处理器核心上,就可以显著提高程序的执行效率,并且随着处理器核心数的不断增加,程序的执行效率也会不断提高。
  2. 更快的响应时间
    有时我们会编写一些业务极为复杂的代码,在单线程的情况下,用户请求的响应时间往往会很长,此时我们就需要使用多线程技术,将一些数据一致性不强的操作派发给其它线程来处理,这样一来,需要响应用户请求的线程就可以更快地处理完成,缩短了响应时间,提升了用户体验。

线程的生命周期

在 Java 中,线程的整个生命周期包含以下六种状态。

有一点需要特别注意:Java 将操作系统中的就绪和运行两种状态统一称为运行状态

线程在整个生命周期中,不会固定的处于某种状态,而是会随着代码的执行在不同的状态之间进行切换,如下图所示。

相关文章