2.4、为什么要引入线程?早期的操作系统都是以进程作为独立运行的基本单位的 , 直到后期计算机科学家们又提出了更小的能独立运行的基本单位 , 也就是线程 。
那为什么要引入线程呢?我们只需要记住这句话:线程又称为迷你进程 , 但是它比进程更容易创建 , 也更容易撤销 。
引入线程之后 , 可以将复杂的操作进一步分解 , 让程序的执行效率进一步提升 。
举个例子 , 进程就如同一个随时背着粮草和机枪的士兵 , 这样肯定会造成士兵的执行战斗的速度 。因此 , 一个简单想法就是:分配两个人来执行 , 一个士兵负责随时背着粮草 , 另一个士兵负责抗机枪战斗 , 这样执行战斗的速度会大幅提升 。这些轻装上阵的士兵 , 可以理解为我们上文提到的线程!
从计算机角度来说 , 由于创建或撤销进程时 , 系统都要为之分配或回收资源 , 如内存空间、I/O 设备等 , 需要较大的时间和空间开销 。
为了减少进程切换的开销 , 把进程作为资源分配单位和调度单位这两个属性分开处理 , 即进程还是作为资源分配的基本单位 , 但是把调度执行与切换的责任交给线程 , 即线程成为独立调度的基本单位 , 它比进程更容易(更快)创建 , 也更容易撤销 。
一句话总结就是:引入线程前 , 进程是资源分配和独立调度的基本单位 。引入线程后 , 进程是资源分配的基本单位 , 线程是独立调度的基本单位 , 线程也是进程中的?个执?单元 。
三、创建线程的方式在 JAVA 里面 , 创建线程有以下两种方式:
- 继承java.lang.Thread类 , 重写run()方法
- 实现java.lang.Runnable接口 , 然后通过一个java.lang.Thread类来启动
在 Java 中 , 通过Thread类来创建并启动线程的步骤如下:
- 1.定义Thread类的?类 , 并重写该类的run()方法
- 2.通过Thread子类 , 初始化线程对象
- 3.通过线程对象 , 调用start()方法启动线程
3.1、继承 Thread 类 , 重写 run 方法介绍
/** * 创建一个 Thread 子类 */public class Thread0 extends Thread {@Overridepublic void run() {for (int i = 0; i < 5; i++) {String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());System.out.println(time + " 当前线程:" + Thread.currentThread().getName() + " , 正在运行");}}} /** * 创建一个测试类 */public class ThreadTest0 {public static void mAIn(String[] args) {// 初始化一个线程对象 , 然后启动线程Thread0 thread0 = new Thread0();thread0.start();for (int i = 0; i < 5; i++) {String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());System.out.println(time + " 当前线程:" + Thread.currentThread().getName() + " , 正在运行");}}}输出结果:2023-08-23 17:58:03:726 当前线程:Thread-0 , 正在运行2023-08-23 17:58:03:727 当前线程:Thread-0 , 正在运行2023-08-23 17:58:03:726 当前线程:main , 正在运行2023-08-23 17:58:03:727 当前线程:Thread-0 , 正在运行2023-08-23 17:58:03:727 当前线程:main , 正在运行2023-08-23 17:58:03:728 当前线程:Thread-0 , 正在运行2023-08-23 17:58:03:728 当前线程:main , 正在运行2023-08-23 17:58:03:728 当前线程:Thread-0 , 正在运行2023-08-23 17:58:03:728 当前线程:main , 正在运行2023-08-23 17:58:03:728 当前线程:main , 正在运行从执行时间上可以看到 , main线程和Thread-0线程交替运行 , 效果十分明显!所谓的多线程 , 其实就是两个及以上线程的代码可以同时运行 , 而不必一个线程需要等待另一个线程内的代码执行完才可以运行 。
推荐阅读
- 四层负载均衡的 NAT 模型与 DR 模型推导
- 详解API接口如何安全的传输数据
- Sonic: Go语言的超级JSON库,解析与编码速度狂飙
- EasyNetQ库:让你的分布式系统消息开发快人一步!
- C# 中的 ref 已经被放开,或许你已经不认识了
- Oracle数据库分区技术:优化大型数据集的存储效率!
- Docker容器中的Postgresql备份脚本异常解决办法
- 目前有哪些比较成功的人工智能应用?
- 为什么色准越高的显示设备就越贵
- AI要被卡脖子了?训练大模型的数据或在2026年耗尽
