news 2026/4/16 10:26:30

JAVA|智能仿真并发项目-进程与线程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JAVA|智能仿真并发项目-进程与线程

文章目录

    • 一、核心概念:程序、进程、线程
      • 1.1 基本定义
      • 1.2 核心关系
    • 二、Java 实现线程的三种方式
      • 2.1 方式 1:继承 `Thread` 类
        • 2.1.1 实现步骤
        • 2.1.2 完整代码示例
        • 2.1.3 核心注意点
      • 2.2 方式 2:实现 `Runnable` 接口(推荐)
        • 2.2.1 实现步骤
        • 2.2.2 完整代码示例
        • 2.2.3 核心优势
      • 2.3 方式 3:实现 `Callable` 接口
        • 2.3.1 适用场景
        • 2.3.2 实现步骤
        • 2.3.3 完整代码示例
    • 三、Thread vs Runnabl
    • 四、线程的生命周期
      • 4.1 生命周期状态
      • 4.2 核心规则
    • 五、总结

一、核心概念:程序、进程、线程

1.1 基本定义

概念本质资源占用作用
程序存储在磁盘上的静态文件(代码文件 + 数据文件)无(仅占用磁盘空间)待执行的指令集合,无法解决问题
进程正在运行的程序,操作系统进行资源分配的最小单元独立内存空间、CPU、IO 等调度系统资源解决具体问题
线程进程的组成部分,CPU 调度执行任务的最小单元共享所属进程的所有资源实现进程内的并发任务

1.2 核心关系

  • 一个进程至少包含一个线程(主线程,如main方法对应的线程),也可包含多个线程
  • 进程之间内存隔离,线程之间内存共享(多线程的核心优势)
  • 操作系统负责管理进程和线程的调度(CPU 时间片轮转)

二、Java 实现线程的三种方式

2.1 方式 1:继承Thread

2.1.1 实现步骤
  1. 定义类继承java.lang.Thread
  2. 重写run()方法(线程的核心执行逻辑,无返回值)
  3. 创建自定义线程类对象,调用start()方法启动线程(不可直接调用run()
2.1.2 完整代码示例
publicclassMyThreadextendsThread{// 线程名称StringthreadName;// 构造方法初始化线程名称publicMyThread(StringthreadName){this.threadName=threadName;}// 重写run方法@Overridepublicvoidrun(){// 模拟线程执行的循环任务for(inti=0;i<100;i++){// 输出线程名称和循环次数System.out.println(threadName+"--"+i);// 休眠10ms,放大线程切换效果try{Thread.sleep(10);}catch(InterruptedExceptione){Thread.currentThread().interrupt();e.printStackTrace();}}}// 测试方法publicstaticvoidmain(String[]args){// 创建线程实例MyThreadmt1=newMyThread("线程A");MyThreadmt2=newMyThread("线程B");// 启动线程mt1.start();mt2.start();// 错误示例:重复启动同一线程,会报错// mt1.start();// 错误示例:直接调用run(),仅为普通方法调用,不会创建新线程// mt1.run();}}
2.1.3 核心注意点
  • start():触发线程创建,等待 CPU 调度,由 JVM 调用run()
  • run():普通方法,直接调用会在主线程中同步执行
  • 单继承限制:Java 不支持多继承,继承Thread后无法继承其他类

2.2 方式 2:实现Runnable接口(推荐)

2.2.1 实现步骤
  1. 定义类实现java.lang.Runnable接口
  2. 重写run()方法(与 Thread 类的run()规则一致)
  3. 创建自定义Runnable实例,作为参数传入Thread构造方法
  4. 调用Thread对象的start()方法启动线程
2.2.2 完整代码示例
publicclassMyRunimplementsRunnable{// 共享变量(多个线程共用一个MyRun实例时,该变量会被共享)intcount=0;StringtaskName;publicMyRun(StringtaskName){this.taskName=taskName;}// 重写run方法@Overridepublicvoidrun(){// 模拟任务执行for(inti=0;i<100;i++){// 多线程共享countcount++;System.out.println(Thread.currentThread().getName()+" | "+taskName+"--"+i+" | 累计计数:"+count);try{Thread.sleep(10);}catch(InterruptedExceptione){Thread.currentThread().interrupt();e.printStackTrace();}}System.out.println(taskName+" 执行完成,最终计数:"+count);}// 测试方法publicstaticvoidmain(String[]args){// 场景1:多个线程执行同一个任务(共享数据)MyRuntask=newMyRun("共享任务");Threadt1=newThread(task,"线程C");Threadt2=newThread(task,"线程D");t1.start();t2.start();// 场景2:多个线程执行不同任务(独立数据)MyRuntask1=newMyRun("独立任务1");MyRuntask2=newMyRun("独立任务2");Threadt3=newThread(task1,"线程E");Threadt4=newThread(task2,"线程F");t3.start();t4.start();}}
2.2.3 核心优势
  • 无单继承限制:实现接口后仍可继承其他类
  • 任务与线程解耦:Runnable封装任务逻辑,Thread负责执行,符合 “单一职责原则”
  • 支持数据共享:多个Thread可共用一个Runnable实例,实现线程间数据共享

2.3 方式 3:实现Callable接口

2.3.1 适用场景

有返回值,可以完成需要获取线程执行结果任务。

2.3.2 实现步骤
  1. 定义类实现java.util.concurrent.Callable<V>接口(V为返回值类型)
  2. 重写call()方法(有返回值)
  3. 创建Callable实例,封装到FutureTask<V>
  4. FutureTask传入Thread构造方法,调用start()启动线程
  5. 通过FutureTask.get()获取线程执行结果
2.3.3 完整代码示例
importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.FutureTask;publicclassMyCallimplementsCallable<Integer>{intstart;intend;publicMyCall(intstart,intend){this.start=start;this.end=end;}@OverridepublicIntegercall()throwsException{intsum=0;for(inti=start;i<=end;i++){sum+=i;Thread.sleep(5);}returnsum;}// 测试方法publicstaticvoidmain(String[]args){// 创建Callable任务:计算1-100的和Callable<Integer>callable=newMyCall(1,100);// 封装为FutureTask(实现了Runnable接口)FutureTask<Integer>futureTask=newFutureTask<>(callable);// 启动线程Threadt=newThread(futureTask);t.start();// 获取执行结果try{Integerresult=futureTask.get();System.out.println("1-100的和:"+result);}catch(InterruptedException|ExecutionExceptione){e.printStackTrace();}}}

三、Thread vs Runnabl

继承 Thread 类实现 Runnable 接口
继承限制受限于 Java 单继承无继承限制,可继承其他类
耦合性线程与任务耦合(类既是线程也是任务)线程与任务解耦(Runnable 是任务,Thread 是执行器)
数据共享需通过静态变量实现,代码复杂多个 Thread 共用一个 Runnable 实例,天然支持共享
代码扩展性差(单继承限制)好(可实现多接口)
适用场景简单独立任务,无需继承其他类复杂任务、需共享数据、需继承其他类

总结

  1. 继承Thread类受单继承限制,实现Runnable接口更灵活
  2. Runnable接口实现了任务与线程的解耦
  3. Runnable支持多个线程共享同一个任务实例,便于线程间数据共享
  4. 一般情况下更推荐使用Runnable接口

四、线程的生命周期

4.1 生命周期状态

状态说明
新建(New)创建 Thread 对象后,未调用start()前的状态
就绪(Runnable)调用start()后,线程进入就绪队列,等待 CPU 调度
运行(Running)CPU 分配时间片,线程执行run()方法中的逻辑
阻塞(Blocked)线程因等待锁、IO、休眠等原因暂停执行,释放 CPU 资源
终止(Terminated)线程执行完run()方法,或因异常终止,生命周期结束

4.2 核心规则

  • 线程从 “新建” 到 “终止” 只能一次,同一个 Thread 对象不能重复调用start()
  • 线程的状态切换由 JVM 和操作系统共同控制,无法手动干预(如无法强制让线程从 “阻塞” 转为 “运行”)

五、总结

  1. 核心概念:进程是资源分配单位,线程是 CPU 调度单位,多线程共享进程内存
  2. 实现方式:继承 Thread(简单但受限)、实现 Runnable(推荐,灵活共享)、实现 Callable(有返回值)
  3. 关键规则:启动线程用start()而非run(),线程生命周期仅一次,Runnable 天然支持数据共享
  4. 学习方向:线程安全(同步锁)、线程池、并发工具类(CountDownLatchCyclicBarrier)等
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:25:26

法律文书检索系统搭建:Qwen3-Embedding-4B实战部署教程

法律文书检索系统搭建&#xff1a;Qwen3-Embedding-4B实战部署教程 1. 为什么法律场景特别需要Qwen3-Embedding-4B&#xff1f; 你有没有遇到过这样的情况&#xff1a;在处理上百份判决书、起诉状、合同范本时&#xff0c;靠关键词搜索只能找到“包含这个词”的文档&#xff…

作者头像 李华
网站建设 2026/4/16 10:26:30

树莓派静态IP设置:适用于智能安防系统的项目应用

以下是对您提供的博文内容进行 深度润色与工程化重构后的版本 。我以一名深耕嵌入式系统多年、常年部署智能安防项目的工程师视角&#xff0c;对原文进行了全面升级&#xff1a; ✅ 彻底去除AI腔调与模板化表达 &#xff08;如“本文将从……几个方面展开”、“综上所述”…

作者头像 李华
网站建设 2026/4/15 10:57:56

FSMN VAD快速上手指南:5步完成音频语音区域精准定位

FSMN VAD快速上手指南&#xff1a;5步完成音频语音区域精准定位 1. 为什么你需要FSMN VAD——语音检测不是“有无”&#xff0c;而是“准不准” 你有没有遇到过这样的情况&#xff1a;会议录音里明明有人在说话&#xff0c;但语音识别系统却报错“未检测到有效语音”&#xf…

作者头像 李华
网站建设 2026/4/15 22:32:22

TurboDiffusion电商应用案例:商品展示视频自动生成部署教程

TurboDiffusion电商应用案例&#xff1a;商品展示视频自动生成部署教程 1. 为什么电商需要TurboDiffusion&#xff1f; 你有没有遇到过这些情况&#xff1f; 每天上新10款商品&#xff0c;每款都要拍3条不同角度的短视频&#xff0c;摄影师排期排到下周&#xff1b;主图点击…

作者头像 李华