文章22 | 阅读 7602 | 点赞0
进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的,系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程与进程类似,但线程是一个比进程更小的执行单元,一个进程在执行过程中可以产生多个线程,线程是操作系统调度的最小单元。
在 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 在同一时刻可以执行多个任务,这些任务之间就是并行关系。
下图很形象地表明了并发和并行的区别:并发是两个队伍交替使用一台咖啡机;并行是两个队伍同时使用两台咖啡机。
在 Java 中,线程的整个生命周期包含以下六种状态。
有一点需要特别注意:Java 将操作系统中的就绪和运行两种状态统一称为运行状态。
线程在整个生命周期中,不会固定的处于某种状态,而是会随着代码的执行在不同的状态之间进行切换,如下图所示。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41685207/article/details/108675007
内容来源于网络,如有侵权,请联系作者删除!