java中线程创建的四种方式

在 Java 中,创建线程主要有以下四种方式,每种方式都有其特点和适用场景:

1. 继承 Thread 类

这是最基础的线程创建方式,通过继承Thread类并重写其run()方法来定义线程执行体。

// 定义线程类
class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的任务
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " 执行: " + i);
            try {
                Thread.sleep(100); // 模拟耗时操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 使用线程
public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        
        thread1.setName("线程1");
        thread2.setName("线程2");
        
        // 启动线程,会自动调用run()方法
        thread1.start();
        thread2.start();
    }
}

特点

  • 简单直接,通过继承实现
  • 缺点是 Java 单继承限制,继承 Thread 后不能再继承其他类
  • 适合简单的线程任务

2. 实现 Runnable 接口

通过实现Runnable接口的run()方法来定义线程任务,然后将其传递给 Thread 对象。

// 实现Runnable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的任务
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " 执行: " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 使用线程
public class RunnableExample {
    public static void main(String[] args) {
        // 创建任务对象
        MyRunnable task = new MyRunnable();
        
        // 创建线程并关联任务
        Thread thread1 = new Thread(task, "线程1");
        Thread thread2 = new Thread(task, "线程2");
        
        // 启动线程
        thread1.start();
        thread2.start();
    }
}

特点

  • 避免了单继承限制,一个类可以同时实现多个接口
  • 适合多个线程共享同一个任务资源的场景
  • 代码结构更清晰,任务与线程控制分离

3. 实现 Callable 接口

Callable接口是 Java 5 引入的,与Runnable类似但可以返回结果,并且可以抛出异常。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

// 实现Callable接口,泛型指定返回值类型
class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 5; i++) {
            sum += i;
            System.out.println(Thread.currentThread().getName() + " 计算: " + i);
            Thread.sleep(100);
        }
        return sum; // 返回计算结果
    }
}

// 使用Callable
public class CallableExample {
    public static void main(String[] args) {
        // 创建Callable任务
        MyCallable callable = new MyCallable();
        
        // 将Callable包装成FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        
        // 创建线程并启动
        Thread thread = new Thread(futureTask, "计算线程");
        thread.start();
        
        try {
            // 获取线程执行结果,会阻塞直到结果返回
            int result = futureTask.get();
            System.out.println("计算结果: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

特点

  • 可以返回执行结果
  • 可以抛出受检查异常
  • 需要通过FutureTask包装后才能传递给 Thread
  • 适合需要获取线程执行结果的场景

4. 使用线程池

Java 5 引入的Executor框架提供了线程池功能,可以高效管理和复用线程。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

// 线程任务
class Task implements Runnable {
    private int taskId;
    
    public Task(int id) {
        this.taskId = id;
    }
    
    @Override
    public void run() {
        System.out.println("任务 " + taskId + " 由 " + Thread.currentThread().getName() + " 执行");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

// 使用线程池
public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建固定大小的线程池,包含3个线程
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 提交5个任务给线程池
        for (int i = 1; i <= 5; i++) {
            executor.submit(new Task(i));
        }
        
        // 关闭线程池
        executor.shutdown();
    }
}

特点

  • 避免频繁创建和销毁线程的开销
  • 可以控制并发线程数量,防止资源耗尽
  • 提供了丰富的线程管理功能
  • 是实际开发中推荐的线程使用方式

总结与对比

方式优点缺点适用场景
继承 Thread简单直接单继承限制简单的线程任务
实现 Runnable无继承限制,资源共享无法返回结果多线程共享资源
实现 Callable可返回结果,可抛异常用法相对复杂需要获取执行结果
线程池高效管理线程,复用线程需要理解线程池参数实际开发中推荐使用

在实际开发中,推荐使用Runnable接口配合线程池的方式,既避免了单继承限制,又能高效管理线程资源。如果需要获取线程执行结果,则使用Callable接口。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值