Java作业:创建线程的两种方式对比(Thread子类 vs Runnable接口)

Java作业:创建线程的两种方式对比(Thread子类 vs Runnable接口)

一、作业目标

  1. 掌握 Java 中创建线程的两种方式:继承Thread类、实现Runnable接口。

  2. 理解两者的区别及适用场景。

二、两种方式介绍

Java 中实现多线程主要有两种方法:

方式描述
继承 Thread 类自定义类继承java.lang.Thread,重写run()方法,然后创建子类对象并调用start()
实现 Runnable 接口自定义类实现java.lang.Runnable接口,实现run()方法,再将其作为参数传给Thread对象,最后调用start()

三、代码示例对比

方式一:继承 Thread 类

// 1. 继承 Thread 类 class MyThread extends Thread { @Override public void run() { for (int i = 1; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + " - 数字:" + i); } } } // 测试 public class ThreadDemo { public static void main(String[] args) { MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.start(); t2.start(); } }

方式二:实现 Runnable 接口

// 2. 实现 Runnable 接口 class MyRunnable implements Runnable { @Override public void run() { for (int i = 1; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + " - 数字:" + i); } } } // 测试 public class RunnableDemo { public static void main(String[] args) { Thread t1 = new Thread(new MyRunnable()); Thread t2 = new Thread(new MyRunnable()); t1.start(); t2.start(); } }

四、主要区别(重点)

对比维度继承 Thread 类实现 Runnable 接口
资源限制Java 单继承,继承 Thread 后不能再继承其他类还可以继承其他类,更灵活
代码共享多个线程需要操作同一份资源时较麻烦(需用静态变量)天然适合多个线程共享同一个 Runnable 对象(同一份数据)
线程与任务分离线程和任务耦合在一起线程和任务分离,Runnable 代表任务,Thread 代表执行者
使用场景简单、不需要继承其他类时推荐方式,尤其需要共享资源或已继承其他类时
面向对象设计不符合“组合优于继承”原则更符合面向接口编程

重点示例:共享资源情况

// 使用 Runnable 实现多线程卖票(共享 100 张票) class TicketRunnable implements Runnable { private int tickets = 100; @Override public void run() { while (tickets > 0) { System.out.println(Thread.currentThread().getName() + " 卖出一张,剩余:" + --tickets); } } } // 只需一个 Runnable 实例,传给多个 Thread 即可 TicketRunnable task = new TicketRunnable(); new Thread(task).start(); new Thread(task).start();

如果使用继承 Thread 类实现同样的共享卖票,需要将 tickets 设为静态变量,不够优雅。

五、常见误区

  • ❌ 直接调用run()方法:不会启动新线程,只是在当前线程中执行普通方法。

  • ✅ 正确启动线程:调用start()方法。

  • 两种方式最终都是通过Thread类来启动线程,Runnable 只是提供了run()方法的实现。

六、小结

推荐选择原因
优先使用 Runnable 接口1. 避免单继承限制
2. 更适合资源共享
3. 代码与线程解耦,易维护
继承 Thread 类的适用场景非常简单的场景,且不需要继承其他类时(比如小练习)

在实际开发中,Runnable+Thread是更主流的写法。Java 8 之后,甚至可以直接用 Lambda 表达式简化:new Thread(() -> { ... }).start();

通过本次对比,我明白了为什么接口方式更受推荐,也加深了对线程概念的理解。