在 Java 中创建线程主要有以下几种方法:

1. 继承 Thread 类并重写 run() 方法

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

class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的任务
        for (int i = 0; i < 5; i++) {
            System.out.println("Thread " + Thread.currentThread().getId() + ": " + i);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); // 启动线程,会自动调用 run() 方法
    }
}

2. 实现 Runnable 接口

通过实现 Runnable 接口的 run() 方法来定义线程任务,然后将其作为参数传递给 Thread 类的构造方法。

class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的任务
        for (int i = 0; i < 5; i++) {
            System.out.println("Thread " + Thread.currentThread().getId() + ": " + i);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.start(); // 启动线程
    }
}

3. 实现 Callable 接口(有返回值)

Callable 接口与 Runnable 类似,但它的 call() 方法可以返回结果,并且可以抛出异常。通常需要配合 FutureFutureTask 使用。

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

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 10; i++) {
            sum += i;
        }
        return sum; // 返回计算结果
    }
}

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Integer> callable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        
        Thread thread = new Thread(futureTask);
        thread.start();
        
        // 获取线程执行结果
        System.out.println("Sum: " + futureTask.get());
    }
}

4. 使用线程池创建线程

通过 ExecutorService 线程池框架来管理和创建线程,这是推荐的方式,尤其在需要创建多个线程时,可以提高资源利用率。

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

public class Main {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 提交任务给线程池
        for (int i = 0; i < 5; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Thread " + Thread.currentThread().getId() + " is running");
                }
            });
        }
        
        // 关闭线程池
        executor.shutdown();
    }
}

总结

  • 继承 Thread 类:简单直接,但Java单继承限制了灵活性。
  • 实现 Runnable 接口:避免单继承限制,推荐使用。
  • 实现 Callable 接口:适合需要返回结果或可能抛出异常的场景。
  • 线程池:适合需要创建多个线程的场景,能有效管理线程资源,是实际开发中的首选方式。

在实际开发中,通常优先选择实现 RunnableCallable 接口的方式,而非继承 Thread 类,以提高代码的灵活性和可维护性。线程池则更是企业级应用的首选。

如果文章对你有一点点帮助,欢迎【点赞、留言、+ 关注】
您的关注是我创作的动力!若有疑问/交流/需求,欢迎留言/私聊!
多一个朋友多一条路!

更多推荐