Java中Runnable接口怎么用_Java多线程创建方式解析

Runnable接口是Java中定义线程任务逻辑的函数式接口,需配合Thread或线程池执行;它仅含无参无返回的run()方法,实现任务与执行的解耦,常见写法包括实现类、匿名内部类和Lambda表达式。

Runnable接口是Java中创建线程最基础、最常用的方式之一,它不直接创建线程,而是定义线程要执行的任务逻辑。真正启动线程仍需借助Thread类,Runnable只负责“做什么”,Thread负责“怎么执行”。

Runnable的核心作用:解耦任务与执行

Runnable是一个函数式接口,只有一个抽象方法run(),没有返回值、不抛受检异常。它把“要运行的代码”封装成一个对象,让线程执行时调用run()方法——这实现了任务逻辑与线程生命周期管理的分离。

常见写法有三种:

  • 实现Runnable接口的类:定义一个类实现Runnable,重写run(),再传给Thread构造器
  • 匿名内部类:适合一次性简单任务,避免额外定义类
  • Lambda表达式(Java 8+):run()无参无返回,天然适配Lambda,写法最简洁

标准用法示例(含Lambda和传统写法对比)

以下代码完成同一任务:打印5次线程名和序号

✅ Lambda方式(推荐):

new Thread(() -> {
  for (int i = 0; i     System.out.println(Thread.currentThread().getName() + ": " + i);
  }
}).start();

✅ 匿名内部类方式:

new Thread(new Runnable() {
  @Override
  public void run() {
    for (int i = 0; i       System.out.println(Thread.currentThread().getName() + ": " + i);
    }
  }
}).start();

✅ 自定义类方式:

class MyTask implements Runnable {
  public void run() {
    for (int i = 0; i       System.out.println(Thread.currentThread().getName() + ": " + i);
    }
  }
}
new Thread(new MyTask()).start();

为什么不用继承Thread?Runnable更灵活

Java不支持多继承,如果类已继承其他父类,就无法再extends Thread;而实现Runnable接口不影响类的继承关系。

更重要的是,Runnable对象可被多个Thread共享,适合“一份任务、多线程并发执行”的场景。例如:

Runnable task = () -> {
  System.out.println("共享任务执行中:" + Thread.currentThread().getName());
};
n

ew Thread(task, "T1").start();
new Thread(task, "T2").start();
new Thread(task, "T3").start();

三个线程执行的是同一个task实例,逻辑复用清晰,资源开销也更低。

Runnable本身不能直接启动,必须配合Thread或线程池

Runnable不是线程,只是任务描述。想让它跑起来,必须交给Thread实例或ExecutorService:

  • 直接传给Thread构造器,再调用start()(适合简单场景)
  • 提交给ExecutorService(如ThreadPoolExecutor),用submit()或execute()(推荐生产环境)

注意:不要直接调用run()方法——那只是普通方法调用,仍在当前线程执行,不会开启新线程。

错误示范:task.run(); → 同步执行,无并发效果。