《深入理解 Java 中的多线程基础(篇一)》

多线程基础

概述

现代操作系统(Windows,macOS,Linux)都可以执行多任务。多任务就是同时运行多个任务。

例如:播放音乐的同时,浏览器可以进行文件下载,同时可以进行QQ消息的收发。

CPU执行代码都是一条一条顺序执行的,但是,即使是单核CPU,也可以同时运行多个任务。因为操作系统执行多任务实际上就是让CPU对多个任务轮流交替执行。

操作系统轮流让多个任务交替执行,例如,让浏览器执行0.001秒,让QQ执行0.001秒,再让音乐播放器执行0.001秒。在用户使用的体验看来,CPU就是在同时执行多个任务。

1.进程与线程
1.1什么是程序?

​ 程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,可以理解为程序是包含静态代码的文件。例如:浏览器软件、音乐播放器软件等软件的安装目录和文件。

1.2 什么是进程?

​ 进程是程序的一次执行过程,是系统运行程序的基本单位。在Windows系统中,每一个正在执行的exe文件或后台服务,都是一个进程,由操作系统统一管理并分配资源,因此进程是动态的。 例如:正在运行中的浏览器就是一个进程,正在运行中的音乐播放器是另一个进程,同理,正在运行中的QQ和WPS等都是进程。

​ 操作系统运行一个程序,即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着, 同时,每个进程还占有某些系统资源如 CPU时间,内存空间,文件,输入输 出设备的使用权等。

1.3 什么是线程?

​ 某些进程内部还需要同时执行多个子任务。例如,我们在使用WPS时,WPS可以让我们一边打字,一边进行拼写检查,同时还可以在后台进行自动保存和上传云文档,我们把子任务称为线程。线程是进程划分成的更小的运行单位。

​ 进程和线程的关系就是:一个进程可以包含一个或多个线程,但至少会有一个主线程。

​ 线程是一个比进程更小的执行单位(CPU的最小执行单位)。一个进程在其执行的过程中可以产生多个线程。与进程不同的是,同类的多个线程共享同一块内存空间和一组系统资源, 所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多。

1.4 进程与线程的区别
  • **根本区别:**进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位;
  • **资源开销:**每个进程都有独立的代码副本和数据空间,进程之间的切换,资源开销较大;线程可以看做轻量级的进程,每个线程都有自己独立的运行栈和程序计数器,线程之间切换,资源开销小;
  • **包含关系:**一个进程内包含有多个线程,在执行过程,线程的执行不是线性串行的,而是多条线程并行共同完成;
  • **内存分配:**同一进程内的所有线程共享本进程的内存空间和资源;进程之间的内存空间和资源相互独立;
  • **影响关系:**一个进程崩溃后,在保护模式下不会对其他进程产生影响;一个线程崩溃,会导致整个进程退出。所以多进程要比多线程健壮;
  • **执行过程:**每个独立的进程有程序运行的入口和程序出口。但是线程不能独立执行,必须依存在应用程序(进程)中,由应用程序提供多个线程执行控制;
1.5 JVM进程的内存区域分配
  • JVM进程启动时,自动创建Heap(堆区)和 Metaspace(元空间,JDK1.8以前叫Method Area方法区);
  • 多个线程共享JVM进程的Heap(堆区)和Metaspace(元空间)资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈。系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,因此,线程也被称为轻量级进程。

1.6 JVM进程由哪些线程组成?

java 复制代码
public class Main {
   public static void main(String[] args) {
       // 获取 Java 线程管理对象 ThreadMXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        // 不需要获取的锁监视器 lockedMonitor 和 synchronizer 信息
      // 仅获取线程和线程信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
       // 遍历线程信息,仅打印线程 ID 和线程名称信息
       for (ThreadInfo threadInfo : threadInfos) {
           System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
       }
   }
}
xml 复制代码
输出结果:
[6] Monitor Ctrl-Break      idea工具独有线程(run模式)
[5] Attach Listener      添加事件监听器
[4] Signal Dispatcher      分发处理给 JVM 信号的线程
[3] Finalizer       调用对象 finalize 方法的线程
[2] Reference Handler      清除 reference 线程
[1] main      主线程
2. 线程基本概念
  • **单线程:**单线程就是进程中只有一个线程。单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
java 复制代码
public class SingleThread {
  	public static void main(String[] args) {
        for (int i = 0; i < 10000; i++) {
            System.out.print(i + " ");
          }
  	}
}
  • **多线程:**由一个以上的线程组成的程序称为多线程程序。Java中,一定是从主线程开始执行(main方法),然后在主线程的某个位置创建并启动新的线程。
java 复制代码
public class MultiThread {
	public static void main(String[] args) {
       // 创建2个线程
	Thread t1 = new Thread(new Runnable() {
		@Override
		public void run() {
		for (int i = 0; i < 10000; i++) {
				System.out.println("线程1:" + i + " ");
			}
		}
		});
	Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10000; i++) {
				System.out.println("线程2:" + i + " ");
				}
			}
		});
      // 启动2个线程
		t1.start();
		t2.start();
	}
}
				System.out.println("线程2:" + i + " ");
				}
			}
		});
      // 启动2个线程
		t1.start();
		t2.start();
	}
}
相关推荐
考虑考虑2 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261353 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊4 小时前
Java学习第22天 - 云原生与容器化
java
渣哥5 小时前
原来 Java 里线程安全集合有这么多种
java
间彧5 小时前
Spring Boot集成Spring Security完整指南
java
间彧6 小时前
Spring Secutiy基本原理及工作流程
java
Java水解7 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆9 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学9 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole9 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端