news 2026/8/21 17:35:12

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/8/21 21:41:43

除了抓包失败,Burp Suite还有哪些新手常遇到的配置问题?

除了抓包失败&#xff0c;Burp Suite新手还常遇到以下配置问题&#xff1a;一、证书配置问题证书未正确信任是新手最常遇到的HTTPS抓包问题。即使下载了Burp的CA证书&#xff0c;如果未导入到浏览器的"受信任的根证书颁发机构"存储区&#xff0c;浏览器仍会提示"…

作者头像 李华
网站建设 2026/8/21 21:41:53

Spring Boot 开发入门:从 0 到 1 搭建第一个 Web 项目

前言 Spring Boot 是由 Pivotal 团队推出的基于 Spring 框架的轻量级开发框架&#xff0c;它简化了 Spring 应用的配置流程&#xff0c;通过 “约定大于配置” 的核心思想&#xff0c;让开发者无需繁琐的 XML 配置就能快速搭建和运行项目。本文将从环境准备、项目创建、核心代…

作者头像 李华
网站建设 2026/8/16 20:05:46

JSP 指令

JSP 指令 引言 JavaServer Pages(JSP)是一种用于创建动态网页的技术。在JSP页面中,指令是一种特殊的元素,用于在JSP页面中提供配置信息。JSP指令可以影响JSP页面的编译、加载和执行过程。本文将详细介绍JSP指令的相关知识,包括其类型、语法和用途。 JSP指令的类型 JSP…

作者头像 李华
网站建设 2026/8/21 1:53:02

月视图统计-Cordovaopenharmony长期习惯分析

一、功能概述 如果说周视图帮助用户了解短期变化趋势&#xff0c;那么月视图则更适合观察长期习惯。本篇文章围绕“月视图统计”页面&#xff0c;介绍如何在 Cordova Web 层 以日为单位聚合整个月的喝水数据&#xff0c;并通过 OpenHarmony ArkTS 提供原生侧的月度概览展示&…

作者头像 李华
网站建设 2026/8/20 7:13:43

Java常见技术分享-09-模版方法模式

什么是模版方法模式&#xff1f; 首先 模版方法模式&#xff0c; 应用于 假如你需要实现多个算法&#xff0c; 同时这些算法的 整体流程 一样&#xff0c; 只是在一些环节 上有自己独特的处理&#xff0c; 就可以用这个模式。 通常包含两个组件&#xff0c; 一个是抽象父类&…

作者头像 李华
网站建设 2026/8/21 23:33:25

SQLite - PHP 数据库交互指南

SQLite - PHP 数据库交互指南 引言 SQLite 是一款轻量级的数据库,被广泛应用于各种场合,包括嵌入式设备、网站和应用软件。PHP 是一种流行的服务器端脚本语言,与 SQLite 数据库的结合使用使得数据库的创建、查询、更新和删除操作变得异常简便。本文将详细探讨如何在 PHP 中…

作者头像 李华