创建线程的三种方式:继承Thread、Runnable 接口、Callable 接口

当在Java中创建线程时,有以下3种方法:

通过实现Runnable接口:

这是Java中创建线程的推荐方式,因为它允许你分离线程的任务(run 方法)与线程的执行。以下是创建线程的步骤:

  • 创建一个实现Runnable接口的类,该接口包含一个run方法,这个方法将定义线程要执行的任务。

    java 复制代码
    class MyRunnable implements Runnable {
        @Override
        public void run() {
            // 线程要执行的任务
            System.out.println("线程执行了任务");
        }
    }   
  • 创建一个Thread对象,将Runnable实例传递给它,并调用start方法启动线程。

    java 复制代码
    MyRunnable myRunnable = new MyRunnable();
    Thread thread = new Thread(myRunnable);
    thread.start();

    这会创建一个新的线程并执行run方法中定义的任务。

通过继承Thread类:

这是另一种创建线程的方式,但通常不被推荐,因为它将线程的任务和线程本身耦合在一起。以下是创建线程的步骤:

  • 创建一个继承自Thread类的子类,并覆盖run方法,定义线程要执行的任务。

    java 复制代码
    class MyThread extends Thread {
        @Override
        public void run() {
            // 线程要执行的任务
            System.out.println("线程执行了任务");
        }
    }
  • 创建子类的实例,并调用start方法以启动线程。

    java 复制代码
    MyThread myThread = new MyThread();
    myThread.start();

    这将创建一个新的线程并执行run方法中定义的任务。

无论你是选择实现Runnable接口还是继承Thread类,都需要明确指定线程要执行的任务,并在run方法中编写相应的代码。通常情况下,使用Runnable接口是更灵活和推荐的方式,因为它允许你将相同的任务传递给多个线程,而继承Thread类可能会导致类的单继承限制问题。

Callable 接口是 Java 中用于支持多线程编程的另一个关键接口。

Runnable 相比,Callable 具有一些附加功能,主要是它允许线程返回一个值或抛出异常。这对于需要获取线程执行结果或者处理可能抛出异常的任务非常有用。

  • Callable 接口: Callable 接口定义了一个名为 call 的方法,该方法在线程执行时返回一个结果或抛出异常。这个接口在 java.util.concurrent 包中定义。
  • Future 接口: 通常,当你使用 Callable 时,你会得到一个 Future 对象,它代表了异步计算的结果。Future 允许你在需要时获取线程的返回值,或者等待线程的执行完成。
  • ExecutorService 为了执行 Callable 对象,通常会使用 ExecutorService 接口,它是线程池的一种实现。ExecutorService 允许你提交 Callable 任务并管理线程的执行。

下面是一个Callable接口创建线程示例:

java 复制代码
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

public class CallableExample {
    public static void main(String[] args) {
        // 创建一个 ExecutorService,通常使用它来管理线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 创建一个 Callable 任务
        Callable<String> task = new MyCallable();

        // 提交 Callable 任务给 ExecutorService,获取 Future 对象
        Future<String> future = executorService.submit(task);

        try {
            // 阻塞并等待任务执行完成,并获取结果
            String result = future.get();
            System.out.println("Callable任务的结果: " + result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 关闭 ExecutorService
        executorService.shutdown();
    }
}

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        // 模拟一个耗时操作
        Thread.sleep(2000);
        return "Callable 任务已完成";
    }
}

使用 Callable 的主要优点包括:

  • 可以返回线程执行的结果,这在需要处理线程结果的情况下非常有用。
  • 可以抛出受检异常,允许更灵活地处理错误情况。
  • 可以使用 Future 对象跟踪线程的执行状态和结果。

此外,Java还提供了线程池的概念,可以更好地管理线程的生命周期和资源。

线程池用法示例:http://t.csdnimg.cn/TWyr9

相关推荐
前进的李工13 分钟前
MySQL用户管理与权限控制指南(含底层架构说明)
开发语言·数据库·sql·mysql·架构
少司府18 分钟前
C++基础入门:类和对象(中)
c语言·开发语言·c++·类和对象·运算符重载·默认成员函数
橘子编程31 分钟前
操作系统原理:从入门到精通全解析
java·linux·开发语言·windows·计算机网络·面试
唔6633 分钟前
原生 Android(Kotlin)仅串口「继承架构」完整案例二
android·开发语言·kotlin
错把套路当深情34 分钟前
Kotlin 全方向开发技术栈指南
开发语言·kotlin
飞Link40 分钟前
LangGraph 核心架构解析:节点 (Nodes) 与边 (Edges) 的工作机制及实战指南
java·开发语言·python·算法·架构
xuhaoyu_cpp_java1 小时前
Boyer-Moore 投票算法
java·经验分享·笔记·学习·算法
JavaEdge.1 小时前
Chrome加载已解压的扩展程序-清单文件缺失或不可读取 无法加载清单
java
iReachers1 小时前
HTML打包EXE配置管理教程:多项目打包设置一键保存、加载与切换
java·前端·javascript
武藤一雄1 小时前
WPF中ViewModel之间的5种通讯方式
开发语言·前端·microsoft·c#·wpf