Blog Post

如何在Java中进行多线程编程

在Java中进行多线程编程有多种方式,最常用的包括继承Thread类、实现Runnable接口、实现Callable接口,以及使用线程池等。以下是具体介绍和代码示例:

1. 继承Thread类通过继承Thread类并重写run()方法来定义线程执行逻辑,然后调用start()方法启动线程。

代码语言:java复制// 继承Thread类

class MyThread extends Thread {

@Override

public void run() {

for (int i = 0; i < 5; i++) {

System.out.println("线程" + Thread.currentThread().getId() + ": " + i);

try {

Thread.sleep(100); // 休眠100毫秒,模拟任务耗时

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public class ThreadExample {

public static void main(String[] args) {

// 创建并启动线程

MyThread thread1 = new MyThread();

MyThread thread2 = new MyThread();

thread1.start(); // 启动线程(调用run()方法)

thread2.start();

}

}2. 实现Runnable接口实现Runnable接口的run()方法,将任务逻辑与线程分离,更灵活(可避免单继承限制)。

代码语言:java复制// 实现Runnable接口

class MyRunnable implements Runnable {

@Override

public void run() {

for (int i = 0; i < 5; i++) {

System.out.println("线程" + Thread.currentThread().getId() + ": " + i);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public class RunnableExample {

public static void main(String[] args) {

// 创建任务实例

MyRunnable task = new MyRunnable();

// 通过Thread包装任务并启动

Thread thread1 = new Thread(task);

Thread thread2 = new Thread(task);

thread1.start();

thread2.start();

}

}3. 实现Callable接口(带返回值)Callable接口与Runnable类似,但call()方法可以返回结果并抛出异常,通常配合Future使用。

代码语言:java复制import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

// 实现Callable接口(泛型指定返回值类型)

class MyCallable implements Callable {

private int taskId;

public MyCallable(int taskId) {

this.taskId = taskId;

}

@Override

public Integer call() throws Exception {

int sum = 0;

for (int i = 0; i <= 10; i++) {

sum += i;

Thread.sleep(50);

}

System.out.println("任务" + taskId + "执行完毕,结果为:" + sum);

return sum; // 返回计算结果

}

}

public class CallableExample {

public static void main(String[] args) throws ExecutionException, InterruptedException {

// 创建Callable任务

MyCallable task1 = new MyCallable(1);

MyCallable task2 = new MyCallable(2);

// 用FutureTask包装Callable(可获取结果)

FutureTask future1 = new FutureTask<>(task1);

FutureTask future2 = new FutureTask<>(task2);

// 启动线程

new Thread(future1).start();

new Thread(future2).start();

// 获取任务结果(会阻塞直到任务完成)

int result1 = future1.get();

int result2 = future2.get();

System.out.println("主线程获取结果:" + result1 + "," + result2);

}

}4. 使用线程池(推荐)频繁创建销毁线程会消耗资源,线程池可以复用线程,提高效率。Java通过Executors或ThreadPoolExecutor创建线程池。

代码语言:java复制import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ThreadPoolExample {

public static void main(String[] args) {

// 创建固定大小的线程池(3个线程)

ExecutorService executor = Executors.newFixedThreadPool(3);

// 提交5个任务到线程池

for (int i = 0; i < 5; i++) {

final int taskId = i;

executor.submit(() -> { // 使用Lambda表达式简化Runnable

System.out.println("任务" + taskId + "由线程" + Thread.currentThread().getId() + "执行");

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

});

}

// 关闭线程池(不再接受新任务,等待现有任务完成)

executor.shutdown();

}

}核心概念补充**线程状态**:新建(New)→ 就绪(Runnable)→ 运行(Running)→ 阻塞(Blocked/Waiting/Timed Waiting)→ 终止(Terminated)。**线程同步**:多线程共享资源时需避免竞争,可使用synchronized关键字、Lock接口等实现同步。**线程通信**:通过wait()、notify()、notifyAll()等方法实现线程间协作。线程池是实际开发中推荐的方式,因为它能更好地管理线程资源,避免频繁创建线程的开销。