什么是 Runnable
-
Runnable 接口是用来定义一个任务的接口,这个任务可以在线程中执行。通俗地说,它就像一个“待办事项”,用来描述需要在一个单独的线程中完成的工作。Runnable 接口非常简单,只定义了一个方法:
run()
。当一个类实现了 Runnable 接口时,它需要提供这个方法的实现,里面写上你想要在新线程中执行的代码public interface Runnable { void run(); }
使用 Runnable 的场景
- 开发一个应用程序时,需要在后台执行一些任务,比如处理文件、下载数据或者执行耗时的计算。不希望这些任务阻塞主线程(特别是在图形用户界面应用中,阻塞主线程会导致界面卡顿)时。就可以使用 Runnable 来创建一个新的任务,并把它交给一个线程去处理
Runnable 接口的使用
-
实现 Runnable 接口:创建一个类来实现 Runnable 接口,并重写
run()
方法。在这个方法里,编写想要执行的代码public class MyRunnable implements Runnable { @Override public void run() { // 这里是你希望在线程中执行的代码 for (int i = 0; i < 5; i++) { System.out.println("Hello from a thread! " + i); try { Thread.sleep(1000); // 让线程休眠1秒 } catch (InterruptedException e) { e.printStackTrace(); } } } }
-
创建线程并传入 Runnable 实例:创建一个 Thread 对象,并传入创建的 Runnable 实例。然后调用
start()
方法来启动线程public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); // 创建Runnable实例 Thread thread = new Thread(myRunnable); // 创建一个线程并传入Runnable实例 thread.start(); // 启动线程 // 主线程可以继续做其他事情 for (int i = 0; i < 5; i++) { System.out.println("Hello from the main thread! " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
- 运行这个程序时,你会看到两个“Hello”消息交替输出,一个来自主线程,一个来自新的线程
Runnable 和 Thread 的区别解析
-
Runnable 是一个接口:它只包含一个
run()
方法,用来定义需要在线程中执行的任务逻辑 -
Thread 是一个类:它本身是一个线程,它可以直接调用
start()
方法来启动线程 -
关注点区别:Runnable 和 Thread 的设计体现了面向对象编程中的关注点分离原则。Runnable 关注的是“要做什么事情”,而 Thread 关注的是“如何去做这件事情”
Runnable 接口的好处
-
灵活性:通过实现 Runnable 接口,一个类可以继续继承其他类,因为 Java 是单继承的。但如果直接继承 Thread 类,那么这个类就不能继承其他类了
-
任务与线程的分离:使用 Runnable 可以将任务的定义与执行分开,让一个任务可以在多个线程中执行,或者在某些情况下可以复用
-
更好的面向对象设计:使用 Runnable 接口能更好地实现对象的解耦,让任务的执行方式更加灵活和可控
总结
- Runnable 接口是实现多线程的一种简单而灵活的方式。通过实现 Runnable 接口并将其传递给 Thread 对象,我们可以很容易地在程序中创建和管理多个线程,确保每个任务都能在后台高效地运行而不阻塞主线程的执行