跳转到内容

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 vs Thread
特性 Runnable接口 Thread类
实现接口 | 继承类
轻量(可共享实例) | 较重(每个线程独立实例)
可同时实现其他接口 | 单继承限制

线程生命周期图[编辑 | 编辑源代码]

stateDiagram-v2 [*] --> New New --> Runnable: start() Runnable --> Running: 线程调度 Running --> Terminated: run()完成 Running --> Runnable: yield()/时间片用完 Running --> Blocked: 等待I/O/锁 Blocked --> Runnable: 资源可用

实际应用案例[编辑 | 编辑源代码]

文件批量处理器[编辑 | 编辑源代码]

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示例所示。

数学建模[编辑 | 编辑源代码]

线程执行时间可表示为: Ttotal=i=1n(Tcpu_i+Tio_i) 其中:

  • Tcpu_i = 第i个线程的CPU时间
  • Tio_i = 第i个线程的I/O等待时间

最佳实践[编辑 | 编辑源代码]

1. 优先选择Runnable而非继承Thread 2. 保持run()方法简洁 3. 处理InterruptedException 4. 避免共享可变状态 5. 使用线程池管理资源