news 2026/2/7 23:21:37

初识线程:带你理解程序运行的基本流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
初识线程:带你理解程序运行的基本流程

一、基本概念

开发程序是为了解决问题

1.程序

一个存在磁盘中的程序(一份文件 代码文件+数据文件)不能解决问题

2.进程

正在运行中的程序 代码和数据 都在内存中

  • 可以解决问题:通过(代码-计算机指令)调度计算机资源(CPU缓存、RAM磁盘、IOSystem IO操作系统)来解决问题
  • 当一个计算机需要同时运行多个进程时,需要操作系统来帮忙
  • 当一个程序需要同时进行多个任务时,需要使用线程
  • 操作系统分配资源的最小单元

3.线程

  • 一个进程的组成部分,任何一个进程都至少有一个线程
  • 进程也需要操作系统帮忙管理线程
  • CPU分配执行任务的最小单元 就是线程
  • 进程使用多线程的优势是:可以共享数据

二、线程

1.Java中实现线程的方式

(1)继承父类(Thread)

  • 继承:public class MyThread extends Thread{ }
  • 重写方法run: public void run( ){ }
  • 将需要独立放在线程中执行的代码写在run方法中
  • 启动线程:使用MyThread类 创建对象并且调用start方法(不可调用run)

eg.创建继承 Thread 的类

/** * 继承 Thread 类的自定义线程类 */ public class MyThread extends Thread { private String threadName; // 构造方法,可以传入线程名称 public MyThread(String name) { this.threadName = name; } /** * 重写 run 方法,包含线程要执行的代码 * 注意:run() 方法是线程的入口点 */ @Override public void run() { System.out.println(threadName + " 线程开始执行..."); try { // 模拟耗时操作 for (int i = 1; i <= 5; i++) { System.out.println(threadName + " - 执行第 " + i + " 次任务"); // 休眠1秒,模拟任务执行时间 Thread.sleep(1000); // 可以调用其他方法 doSomething(i); } } catch (InterruptedException e) { System.out.println(threadName + " 被中断"); } System.out.println(threadName + " 线程执行完毕"); } /** * 线程中可以执行的其他方法 */ private void doSomething(int count) { System.out.println(threadName + " - 正在处理第" + count + "个数据"); } }

使用 MyThread 创建线程并启动

/** * 主类,演示如何使用 MyThread 创建和启动线程 */ public class ThreadExample { public static void main(String[] args) { System.out.println("主线程开始执行..."); // 示例1: 创建单个线程 System.out.println("=== 示例1: 创建单个线程 ==="); // 第一步: 创建 MyThread 对象 MyThread thread1 = new MyThread("线程A"); // 第二步: 调用 start() 方法启动线程 thread1.start(); // 注意:不要调用 run() 方法 // 验证直接调用 run() 和调用 start() 的区别 System.out.println("\n=== 测试直接调用 run() 方法 ==="); MyThread testThread = new MyThread("测试线程"); // 直接调用 run() 方法(错误示例) System.out.println("直接调用 run() 方法:"); testThread.run(); // 这会在当前线程(主线程)中执行,不会创建新线程 System.out.println("\n=== 测试调用 start() 方法 ==="); MyThread testThread2 = new MyThread("正确线程"); testThread2.start(); // 正确:会在新线程中执行 // 主线程继续执行其他任务 for (int i = 0; i < 3; i++) { System.out.println("主线程执行任务: " + i); try { Thread.sleep(800); // 主线程休眠 } catch (InterruptedException e) { e.printStackTrace(); } } // 示例2: 创建多个线程 System.out.println("\n=== 示例2: 创建多个线程 ==="); MyThread thread2 = new MyThread("线程B"); MyThread thread3 = new MyThread("线程C"); // 启动多个线程 thread2.start(); thread3.start(); // 等待所有线程执行完毕 try { thread1.join(); // 等待线程1结束 thread2.join(); // 等待线程2结束 thread3.join(); // 等待线程3结束 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("所有线程执行完毕,主线程结束"); } }

(2)实现接口(Runnable)

  • 实现接口:public class MyRun implements Runnable{ }
  • 重写run方法
  • 实现线程中的代码
  • 使用MyRun创建一个对象,将这个对象放在一个Thread类对象的构造方法中,使用Thread对象start方法

eg.创建实现 Runnable 接口的类

/** * 实现 Runnable 接口的类 */ public class MyRun implements Runnable { private String threadName; // 构造方法,可以传入线程名称 public MyRun(String name) { this.threadName = name; } /** * 重写 run 方法,包含线程要执行的代码 */ @Override public void run() { try { for (int i = 1; i <= 5; i++) { // 模拟耗时操作 Thread.sleep(1000); // 休眠1秒 // 打印当前线程信息 System.out.println(threadName + " - 正在执行: " + i); // 可以在run方法中调用其他方法 doSomething(i); } } catch (InterruptedException e) { System.out.println(threadName + " 被中断"); } System.out.println(threadName + " 执行完毕"); } /** * 线程中可以执行的其他方法 */ private void doSomething(int count) { System.out.println(threadName + " - 执行第" + count + "次操作"); } }

使用 MyRun 创建线程并启动

/** * 主类,演示如何使用 MyRun 创建和启动线程 */ public class ThreadExample { public static void main(String[] args) { System.out.println("主线程开始执行..."); // 示例1: 创建单个线程 System.out.println("=== 示例1: 创建单个线程 ==="); // 第一步: 创建 MyRun 对象(实现了Runnable接口) MyRun myRun1 = new MyRun("线程A"); // 第二步: 将 MyRun 对象作为参数创建 Thread 对象 Thread thread1 = new Thread(myRun1); // 第三步: 调用 Thread 对象的 start() 方法启动线程 thread1.start(); // 主线程继续执行其他任务 for (int i = 0; i < 3; i++) { System.out.println("主线程执行任务: " + i); try { Thread.sleep(800); // 主线程休眠 } catch (InterruptedException e) { e.printStackTrace(); } } // 示例2: 创建多个线程 System.out.println("\n=== 示例2: 创建多个线程 ==="); MyRun myRun2 = new MyRun("线程B"); MyRun myRun3 = new MyRun("线程C"); Thread thread2 = new Thread(myRun2); Thread thread3 = new Thread(myRun3); // 启动多个线程 thread2.start(); thread3.start(); // 等待所有线程执行完毕 try { thread1.join(); // 等待线程1结束 thread2.join(); // 等待线程2结束 thread3.join(); // 等待线程3结束 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("所有线程执行完毕,主线程结束"); } }

(3)实现Callable接口(最新,复杂)

目前所学知识无法实现,后续学到会补充

tips.同一个thread对象不可调用多次start函数(同一个线程在一个生命周期内(创建-运行-销毁)只能启动一次)

但同一个runnable接口类可以同时被多个thread运行

2.继承父类和实现接口两种创建线程的方式区别?

(1)继承机制

继承 Thread 类

// 继承 Thread 类 public class MyThread extends Thread { @Override public void run() { // 线程代码 } } // 使用 MyThread thread = new MyThread(); thread.start();

实现 Runnable 接口

// 实现 Runnable 接口 public class MyRunnable implements Runnable { @Override public void run() { // 线程代码 } } // 使用 MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start();

(2)核心区别对比表

对比点继承 Thread 类实现 Runnable 接口
继承限制占用继承位置(Java单继承)不占用继承位置,可以继承其他类
代码结构线程和任务耦合在一起线程和任务分离,更清晰
资源共享相对复杂方便共享资源(同一个Runnable对象)
扩展性较差更好,更灵活
面向对象不符合"组合优于继承"原则符合面向对象设计原则

(3)实际开发中的选择标准

选择继承 Thread 类的情况:
  1. 需要重写 Thread 类的其他方法(如 interrupt())

  2. 简单的单线程任务

  3. 不需要共享资源

  4. 学习或演示目的

选择实现 Runnable 接口的情况:
  1. 需要继承其他类(Java单继承限制)

  2. 需要多个线程共享资源

  3. 使用线程池管理线程

  4. 代码需要更好的可扩展性

  5. 大多数实际项目场景

在绝大多数情况下,应该优先使用实现 Runnable 接口的方式创建线程。只有在需要重写 Thread 类的特定方法时,才考虑继承 Thread 类。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 8:29:28

CGO调用OpenCV实现多角度模板匹配性能分析

在计算机视觉领域&#xff0c;模板匹配作为基础实用的图像处理技术&#xff0c;历经传统方法到深度学习方法的迭代。据国际计算机视觉与模式识别会议&#xff08;CVPR&#xff09;2023年技术趋势报告&#xff0c;传统模板匹配在现代工业视觉检测中仍占38%应用份额&#xff0c;尤…

作者头像 李华
网站建设 2026/2/6 19:06:06

Zookeeper在大数据实时报表系统中的应用

Zookeeper在大数据实时报表系统中的应用 关键词&#xff1a;Zookeeper、大数据、实时报表系统、分布式协调、一致性协议、分布式锁、元数据管理 摘要&#xff1a;本文深入探讨Zookeeper在大数据实时报表系统中的核心应用场景&#xff0c;包括分布式协调、配置管理、集群节点管理…

作者头像 李华
网站建设 2026/2/6 15:52:14

干瞪眼游戏胜率较高的玩法分析

### **干瞪眼游戏胜率较高的玩法分析**在干瞪眼游戏中&#xff0c;玩家需要通过合理出牌、灵活运用牌型和策略性保留关键牌来提高胜率。以下是胜率较高的玩法策略&#xff1a;---#### **1. ** **炸弹的灵活运用** - **核心作用**&#xff1a;炸弹&#xff08;四张相同牌&#x…

作者头像 李华
网站建设 2026/2/7 0:33:45

救命神器10个AI论文平台,专科生毕业论文救星!

救命神器10个AI论文平台&#xff0c;专科生毕业论文救星&#xff01; AI工具助力论文写作&#xff0c;专科生也能轻松应对 随着人工智能技术的不断发展&#xff0c;AI工具已经逐渐成为学术写作中不可或缺的助手。对于许多专科生来说&#xff0c;撰写毕业论文是一项既复杂又耗…

作者头像 李华