news 2026/9/23 22:27:57

Java线程的三种创建方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java线程的三种创建方式

目录

1.线程的概念

2.进程和线程的对比

3.线程创建的三种方式

1)继承Thread类

2)实现Runnable接口

3)实现Callable接口

三种方法的执行流程


1.线程的概念

线程是程序执行流的最小单位,是进程中的一个独立执行单元。一个进程可以包含多个线程,这些线程共享进程的资源,但各自独立执行。


2.进程和线程的对比


3.线程创建的三种方式

1)继承Thread类

/** * 第一种创建线程的方式,继承Thread类 * 优点:代码简单 * 缺点:单继承的局限性,不能再继承其他的类 */ public class Demo1 { public static void main(String[] args) { Thread myThread= new MyThread(); myThread.start(); for (int i = 0; i < 6; i++) { System.out.println("main方法输出:"+ i); } } } class MyThread extends Thread { public void run() { for (int i = 0; i < 6; i++) { System.out.println("子线程输出:" + i); } } }

继承关系:MyThread extends Thread

重写方法:必须重写 run() 方法

启动方式:创建对象后调用 start() 方法

执行机制:

start() 会启动新线程,同时调用 run() 方法

直接调用 run() 只会普通方法调用,不会创建新线程

输出结果特点:主线程和子线程的输出会交替出现,顺序不确定

2)实现Runnable接口

/** * 第二种创建线程的方式:实现Runnable接口 * 优点:只是实现了接口,可以继承其他类,实现其他接口,拓展性强 * 缺点:需要多一个Runnable对象 */ public class Demo2 { // 目标:掌握多线程的第二种创建方式:实现runnable接口 public static void main(String[] args) { //3.创建线程对象,要把这个线程任务类包装成线程类,把这个对象交给线程去处理 Thread MyRunnable = new Thread(new MyRunnable()); MyRunnable.start(); for (int i = 0; i < 6; i++) { System.out.println("Main方法输出:" + i); } } } //1.定义一个线程任务类来实现Runnable接口 class MyRunnable implements Runnable { //2.重写run方法,执行线程任务 @Override public void run() { for (int i = 0; i < 6; i++) { System.out.println("子线程输出:" + i); } } }

实现关系:MyRunnable implements Runnable

重写方法:必须实现 run() 方法

线程创建:需要将 Runnable 对象传给 Thread 构造器

优点:

避免单继承限制

适合多个线程执行相同任务

代码结构更清晰

简化写法

1.匿名内部类
/** * 线程创建的第二种方法的匿名内部类写法 */ public class Demo3 { public static void main(String[] args) { // 使用匿名内部类创建Runnable对象 Thread t1 = new Thread(new Runnable(){ @Override public void run() { for (int i = 0; i < 6; i++) { System.out.println("子线程输出:" + i); } } }); t1.start(); for (int i = 0; i < 6; i++) { System.out.println("Main方法输出:" + i); } } }
2.lambda表达式
// Java 8+ 可以使用Lambda表达式进一步简化 public class Demo2_Lambda { public static void main(String[] args) { // 使用Lambda表达式创建Runnable对象 Thread thread = new Thread(() -> { for (int i = 0; i < 6; i++) { System.out.println("子线程输出:" + i); } }); thread.start(); for (int i = 0; i < 6; i++) { System.out.println("Main方法输出:" + i); } } }

3)实现Callable接口

import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 前面两种创建方式重写的run方法都不能直接返回结果 * JDK5.0提供了Callable接口和FutureTask类来实现 * 第三种创建方式 */ public class Demo4 { public static void main(String[] args) { // 创建Callable接口的实现类对象 Callable<String> c = new MyCallable(100); // 4. 把Callable对象封装成真正的线程任务对象FutureTask对象 FutureTask<String> ft = new FutureTask<>(c); /** * FutureTask对象的作用 * a. 本质是一个Runnable线程任务对象,可以交给Thread线程对象处理 * b. 可以获取线程执行完毕后的结果 */ // 5. 把FutureTask对象作为参数传递给Thread对象 Thread thread = new Thread(ft); thread.start(); // 启动线程 // 创建第二个线程 Callable<String> c1 = new MyCallable(300); FutureTask<String> ft1 = new FutureTask<>(c1); Thread thread1 = new Thread(ft1); thread1.start(); try { // 获取第一个线程的执行结果 // get()方法会阻塞,直到线程执行完成并返回结果 System.out.println(ft.get()); } catch (Exception e) { e.printStackTrace(); } try { // 获取第二个线程的执行结果 System.out.println(ft1.get()); } catch (Exception e) { e.printStackTrace(); } } } // 1. 定义实现类来实现Callable接口 // 泛型参数表示返回值的类型 class MyCallable implements Callable<String> { private Integer n; // 构造方法,传入计算范围 MyCallable(Integer n) { this.n = n; } // 2. 重写call方法,有返回值,可以抛出异常 @Override public String call() throws Exception { Integer sum = 0; for (int i = 1; i <= n; i++) { sum += i; } return "1+.....+" + n + "的输出结果为" + sum; } }

实现关系:MyCallable implements Callable<String>

重写方法:必须实现 call() 方法

关键区别:

call() 方法可以有返回值

call() 方法可以抛出异常

run() 方法没有返回值,不能抛出检查异常

执行流程:
Callable实现类 → FutureTask包装 → Thread包装 → start()启动 → get()获取结果
FutureTask 的作用:

适配器模式:将 Callable 转换成 Runnable

结果容器:存储异步计算结果

阻塞获取:get() 方法会等待线程执行完成

三种方法的执行流程

// 方式1:继承Thread Thread子类 → start() → JVM调用run() // 方式2:实现Runnable Runnable实现类 → 传给Thread → start() → JVM调用run() // 方式3:实现Callable Callable实现类 → FutureTask包装 → 传给Thread → start() → get()获取结果

小结

  1. 优先选择实现 Runnable 接口,配合 Lambda 表达式

  2. 需要返回值时使用 Callable + FutureTask

  3. 避免直接继承 Thread 类

  4. 合理使用线程池管理线程资源

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

【MongoDB实战】6.3 索引优化实战:慢查询解决

文章目录 《MongoDB实战入门》第6章 性能优化:索引与查询效率提升 6.3 索引优化实战:慢查询解决 6.3.1 识别慢查询:explain()方法分析查询执行计划 1. 核心概念铺垫 2. 实操:识别慢查询(准备测试数据+分析执行计划) 6.3.2 优化案例:为慢查询添加合适索引(对比优化前后)…

作者头像 李华
网站建设 2026/9/20 16:39:45

HTML如何设计JQuery支持大文件上传的拖拽功能?

2023年11月2日 星期四 阴有小雨 外包项目日志 - 企业级大文件传输系统Day3 项目背景与架构设计 客户是某地质勘探研究院&#xff0c;每日需上传**20GB**的勘探数据&#xff08;含激光扫描点云、地质剖面图等&#xff09;&#xff0c;要求&#xff1a; 文件夹结构保留&#xf…

作者头像 李华
网站建设 2026/9/23 15:34:12

yolo-ORBSLAM2复现

这个也是一个经典的问题了&#xff0c;我是想复现&#xff0c;再进行修改&#xff0c;因为我不使用yolo作为检测&#xff0c;但要先搞清楚检测框是怎么送入slam的&#xff0c;所以先复现各位大佬们的。主要参考&#xff1a; https://github.com/JinYoung6/orbslam_addsemantic…

作者头像 李华
网站建设 2026/9/23 23:09:55

python基于大数据技术的购房推荐系统的设计与实现

Python基于大数据技术的购房推荐系统的设计与实现是一个复杂但具有广泛应用前景的项目。以下是对该系统的详细介绍&#xff1a; 一、系统概述 购房推荐系统利用Python编程语言的强大功能和丰富的大数据技术&#xff0c;结合机器学习算法和推荐算法&#xff0c;对购房数据进行深…

作者头像 李华
网站建设 2026/9/23 13:53:42

介观交通流仿真软件:DynusT_(20).DynusT在实际项目中的应用

DynusT在实际项目中的应用 在上一节中&#xff0c;我们已经了解了DynusT的基本功能和使用方法。本节将详细介绍如何在实际项目中应用DynusT进行交通流仿真。我们将通过具体的案例来展示如何设置仿真参数、导入交通网络数据、模拟交通流量以及分析仿真结果。这些案例将涵盖城市交…

作者头像 李华
网站建设 2026/9/22 22:44:00

深入JVM(三):JVM执行引擎

JVM执行引擎 一、JVM前后端编译 前端编译&#xff1a;使用编译器将Java文件编译成class字节码文件后端编译&#xff1a;将class字节码文件编译成机器码指令java 跨平台直接理解&#xff1a;前端编译将java文件编译成class文件&#xff0c; 然后使用jvm&#xff08;后端编译&…

作者头像 李华