Java Runnable接口
外观
Java Runnable接口[编辑 | 编辑源代码]
介绍[编辑 | 编辑源代码]
Runnable接口是Java多线程编程的核心接口之一,位于java.lang
包中。它定义了一个单一方法run()
,用于封装需要在独立线程中执行的代码逻辑。与直接继承Thread
类相比,实现Runnable
接口是更灵活的多线程实现方式,因为Java不支持多重继承,而接口可以多重实现。
语法定义[编辑 | 编辑源代码]
Runnable接口的官方定义如下:
@FunctionalInterface
public interface Runnable {
void run();
}
基本用法[编辑 | 编辑源代码]
实现Runnable接口[编辑 | 编辑源代码]
创建一个实现Runnable接口的类,并重写run()
方法:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread is running");
}
}
启动线程[编辑 | 编辑源代码]
通过Thread类启动Runnable实例:
public class Main {
public static void main(String[] args) {
Runnable task = new MyRunnable();
Thread thread = new Thread(task);
thread.start(); // 启动线程
}
}
输出:
Thread is running
使用Lambda表达式[编辑 | 编辑源代码]
Java 8+支持用Lambda简化实现:
public class LambdaExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> System.out.println("Lambda thread running"));
thread.start();
}
}
与Thread类的对比[编辑 | 编辑源代码]
特性 | Runnable接口 | Thread类 |
---|---|---|
实现接口 | 继承类 | ||
轻量(可共享实例) | 较重(每个线程独立实例) | ||
可同时实现其他接口 | 单继承限制 |
线程生命周期图[编辑 | 编辑源代码]
实际应用案例[编辑 | 编辑源代码]
文件批量处理器[编辑 | 编辑源代码]
class FileProcessor implements Runnable {
private String fileName;
public FileProcessor(String name) {
this.fileName = name;
}
@Override
public void run() {
System.out.println("Processing: " + fileName);
// 模拟文件处理耗时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed: " + fileName);
}
}
public class BatchFileDemo {
public static void main(String[] args) {
String[] files = {"A.txt", "B.log", "C.csv"};
for (String file : files) {
new Thread(new FileProcessor(file)).start();
}
}
}
可能的输出顺序(因线程调度而异):
Processing: A.txt Processing: B.log Processing: C.csv Completed: A.txt Completed: B.log Completed: C.csv
高级主题[编辑 | 编辑源代码]
线程池中的Runnable[编辑 | 编辑源代码]
Executor框架更高效地管理Runnable任务:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
Runnable worker = new Task("Task-" + i);
executor.execute(worker);
}
executor.shutdown();
}
}
class Task implements Runnable {
private String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " started by " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " completed");
}
}
常见问题[编辑 | 编辑源代码]
Runnable没有返回值怎么办?[编辑 | 编辑源代码]
如果需要获取执行结果,应使用Callable
接口替代,它定义了call()
方法可以返回结果。
如何传递参数?[编辑 | 编辑源代码]
通过构造函数或setter方法向Runnable实现类传递参数,如前面的FileProcessor示例所示。
数学建模[编辑 | 编辑源代码]
线程执行时间可表示为: 其中:
- = 第i个线程的CPU时间
- = 第i个线程的I/O等待时间
最佳实践[编辑 | 编辑源代码]
1. 优先选择Runnable而非继承Thread
2. 保持run()
方法简洁
3. 处理InterruptedException
4. 避免共享可变状态
5. 使用线程池管理资源