接上
第三个多线程程序
java
package thread.test;
//定义了一个叫MyThread3的类,实现了Runable接口,所以它必须重写run()方法
class MyThread3 implements Runnable {
@Override
public void run() {
//线程执行的具体内容
//进入一个无限循环,每一秒输出一句"hello runnable"
while (true) {
System.out.println("hello runnable");
try {
//让线程睡眠1秒。避免一直疯狂输出
Thread.sleep(1000);
} catch (InterruptedException e) {
//如果睡眠被中断,抛出运行时异常RuntimeException
throw new RuntimeException(e);
}
}
}
}
//主程序入口
public class ThreadDemo3 {
public static void main(String[] args) {
//新建一个线程,线程要执行的人物是MyThread3实现的run()方法
Thread t=new Thread(new MyThread3());
//启动线程,注意:不是调用run(),这样才会新建一个线程
t.start();
//主线程也进入无限循环
while (true) {
//每一秒输出一行"hello main"
System.out.println("hello main");
try {
//让线程休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
//如果休眠中断,抛出运行时异常
throw new RuntimeException(e);
}
}
}
}
Runnable 和 Thread 的区别
特点 | Runnable 接口 |
Thread 类 |
---|---|---|
本质 | 是一个接口 | 是一个类 ,继承自 Object ,实现了 Runnable 接口 |
用途 | 只定义了一个任务(run() 方法),不负责线程的创建 |
既可以定义任务(重写 run() ),也能直接创建和管理线程 |
继承限制 | 可以避免单继承局限(因为类还可以继承别的类) | 继承了 Thread 后,不能再继承其他类(Java 单继承) |
推荐使用场景 | 任务和线程分离,程序更灵活、解耦 | 小项目、简单场景下可以直接继承 Thread 简单快速 |
为什么写 Thread t = new Thread(new MyThread3());
原因就是:
-
new MyThread3()
是一个实现了Runnable
的对象,它描述了线程应该执行什么任务 (即run()
方法里的代码)。 -
new Thread(Runnable target)
这个构造方法,把Runnable
包装进去,真正由Thread
来创建和控制线程。 -
最后通过
t.start()
来开启这个线程,执行MyThread3.run()
里面的逻辑。
简单理解就是:
-
Runnable
负责写任务(要干什么事)。 -
Thread
负责开辟新线程、调度执行这个任务。
打个比方(形象理解)
-
Runnable
就像是工作说明书(比如说明:搬砖、洗衣服、打扫卫生)。 -
Thread
就像是真正的工人,要按照说明书去干活。
你可以写好很多不同的说明书(不同的 Runnable
),然后招很多工人(Thread
)去根据说明来工作。
例子
方式一:实现 Runnable
(推荐 ✅)
java
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("任务开始了");
}
}
public class Test {
public static void main(String[] args) {
Runnable r = new MyRunnable(); // 任务
Thread t = new Thread(r); // 线程 + 任务
t.start(); // 开启线程
}
}
方式二:直接继承 Thread
(简单,但不够灵活)
java
class MyThread extends Thread {
@Override
public void run() {
System.out.println("任务开始了");
}
}
public class Test {
public static void main(String[] args) {
Thread t = new MyThread(); // 直接是线程
t.start(); // 开启线程
}
}
总结一下
-
Runnable
只管写任务,不管线程怎么执行。 -
Thread
既是线程本身,也能直接运行任务。 -
推荐用 Runnable,因为更加灵活,避免继承带来的局限,可以更好地与线程池等高级功能结合。