Java中Thread类的start()和run()的区别

本文详细解析了Java线程的启动与运行机制,包括start()方法与run()方法的区别,以及如何通过实例理解线程执行过程。通过具体代码示例,展示了线程对象调用start()方法启动线程与直接调用run()方法的不同运行结果。
1、start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。 

通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。然后JVM通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程执行体,它包含了要执行的这个线程的内容,run方法运行结束,此线程终止,而CPU再运行其它线程, 

2、run()方法当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码。 

如果直接用run方法,这只是调用一个方法而已,程序中依然只有主线程,只有这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。 

记住:线程就是为了更好地利用CPU,提高程序运行速率的! 

为了更好地理解两者的区别,看以下的例子: 
例程1: 
Java代码  收藏代码
  1. public class TestThread {  
  2.     public static void main(String arg[]){  
  3.         NewThread t1 = new NewThread();  
  4.         NewThread t2 = new NewThread();  
  5.         Thread th1 = new Thread(t1);  
  6.         Thread th2 = new Thread(t2);  
  7.         System.out.println(Thread.currentThread().getName() );  
  8.         th1.start();  
  9.         th2.start();  
  10.         //th1.run();  
  11.         //th2.run();  
  12.     }  
  13. }  
  14. class NewThread implements Runnable{  
  15.     int i = 0;  
  16.     public void run() {  
  17.         for(int i = 0; i <20;i ++){  
  18.             System.out.println(Thread.currentThread().getName() +"   "+ i);  
  19.         }  
  20.     }  
  21. }  

程序的运行结果1(//th1.run();//th2.run();): 
main 
Thread-0   0 
Thread-0   1 
Thread-1   0 
Thread-0   2 
Thread-1   1 
Thread-1   2 
Thread-0   3 
Thread-1   3 
Thread-0   4 
Thread-1   4 
Thread-0   5 
Thread-0   6 
Thread-1   5 
Thread-0   7 
Thread-1   6 
Thread-0   8 
Thread-1   7 
Thread-0   9 
Thread-1   8 
Thread-0   10 
Thread-0   11 
Thread-0   12 
Thread-1   9 
Thread-0   13 
Thread-0   14 
Thread-1   10 
Thread-0   15 
Thread-0   16 
Thread-1   11 
Thread-0   17 
Thread-1   12 
Thread-0   18 
Thread-1   13 
Thread-0   19 
Thread-1   14 
Thread-1   15 
Thread-1   16 
Thread-1   17 
Thread-1   18 
Thread-1   19
 
程序的运行结果2:(//th1.start();//th2.start();) 
main 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19
 

运行结果分析:线程对象调用start()方法,就表示启动了线程,即又产生了一条执行线索。而调用run()方法,只是相当于普通的方法调用,并没有产生新的执行线索,run()方法仍然在调用它的线程中执行。 

如下图1为两种不同情况的比较: 

Java中Thread类的start()和run()的区别 - ivan - Ivan的技术空间

假设将程序中的注释都去掉: 
例程2: 
Java代码  收藏代码
  1. public class TestThread {  
  2.     public static void main(String arg[]){  
  3.         NewThread t1 = new NewThread();  
  4.         NewThread t2 = new NewThread();  
  5.         Thread th1 = new Thread(t1);  
  6.         Thread th2 = new Thread(t2);  
  7.         System.out.println(Thread.currentThread().getName());  
  8.         th1.start();  
  9.         th2.start();  
  10.         th1.run();  
  11.         th2.run();  
  12.     }  
  13. }  
  14. class NewThread implements Runnable{  
  15.     int i = 0;  
  16.     public void run() {  
  17.         for(int i = 0; i <20;i ++){  
  18.             System.out.println(Thread.currentThread().getName() +"   "+ i);  
  19.         }  
  20.     }  
  21. }  

程序的运行结果如下: 
第一种结果: 
main 
Thread-0   0 
Thread-1   0 
Thread-1   1 
Thread-1   2 
main   0 
Thread-1   3 
Thread-0   1 
Thread-1   4 
main   1 
main   2 
main   3 
main   4 
main   5 
Thread-1   5 
Thread-0   2 
Thread-0   3 
Thread-0   4 
Thread-0   5 
Thread-0   6 
Thread-0   7 
Thread-1   6 
Thread-1   7 
main   6 
Thread-1   8 
Thread-0   8 
Thread-0   9 
Thread-1   9 
main   7 
Thread-1   10 
Thread-0   10 
Thread-1   11 
main   8 
main   9 
Thread-1   12 
Thread-0   11 
Thread-1   13 
Thread-1   14 
Thread-1   15 
main   10 
Thread-1   16 
Thread-1   17 
Thread-0   12 
Thread-1   18 
main   11 
Thread-1   19 
Thread-0   13 
Thread-0   14 
main   12 
main   13 
main   14 
Thread-0   15 
main   15 
Thread-0   16 
main   16 
main   17 
Thread-0   17 
main   18 
Thread-0   18 
main   19 
Thread-0   19
 
第二种结果: 
main 
main   0 
Thread-0   0 
Thread-1   0 
Thread-0   1 
main   1 
main   2 
Thread-0   2 
Thread-1   1 
Thread-0   3 
main   3 
main   4 
Thread-0   4 
Thread-0   5 
Thread-0   6 
Thread-0   7 
Thread-1   2 
Thread-0   8 
main   5 
Thread-0   9 
Thread-1   3 
Thread-0   10 
main   6 
Thread-0   11 
Thread-1   4 
Thread-0   12 
main   7 
Thread-0   13 
Thread-1   5 
Thread-0   14 
main   8 
Thread-0   15 
Thread-1   6 
Thread-0   16 
main   9 
Thread-0   17 
Thread-1   7 
Thread-0   18 
main   10 
Thread-0   19 
Thread-1   8 
main   11 
Thread-1   9 
main   12 
Thread-1   10 
Thread-1   11 
main   13 
Thread-1   12 
Thread-1   13 
Thread-1   14 
main   14 
Thread-1   15 
main   15 
Thread-1   16 
main   16 
main   17 
Thread-1   17 
main   18 
Thread-1   18 
main   19 
Thread-1   19 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19
 
问题:为什么会产生这两种结果? 

例程3: 
Java代码  收藏代码
  1. public class TestThread {  
  2.     public static void main(String arg[]){  
  3.         NewThread t1 = new NewThread();  
  4.         NewThread t2 = new NewThread();  
  5.         Thread th1 = new Thread(t1);  
  6.         Thread th2 = new Thread(t2);  
  7.             th1.start();  
  8.         th2.start();  
  9.         for(int i = 0; i <20;i ++){  
  10.             System.out.println(Thread.currentThread().getName() +"   "+ i);  
  11.         }  
  12.         th1.run();  
  13.         th2.run();  
  14.     }  
  15. }  
  16. class NewThread implements Runnable{  
  17.     int i = 0;  
  18.     public void run() {  
  19.         for(int i = 0; i <20;i ++){  
  20.             System.out.println(Thread.currentThread().getName() +"   "+ i);  
  21.         }  
  22.     }  
  23. }  

程序的运行结果如下: 
第一种结果: 
main   0 
main   1 
Thread-0   0 
Thread-1   0 
Thread-1   1 
Thread-0   1 
Thread-0   2 
main   2 
Thread-0   3 
Thread-1   2 
Thread-0   4 
Thread-0   5 
main   3 
Thread-0   6 
Thread-1   3 
Thread-0   7 
main   4 
main   5 
Thread-0   8 
Thread-0   9 
Thread-1   4 
Thread-1   5 
Thread-1   6 
Thread-0   10 
main   6 
Thread-0   11 
Thread-1   7 
Thread-0   12 
Thread-0   13 
Thread-0   14 
main   7 
main   8 
main   9 
main   10 
Thread-0   15 
Thread-0   16 
Thread-1   8 
Thread-0   17 
main   11 
Thread-0   18 
Thread-1   9 
Thread-1   10 
Thread-1   11 
Thread-0   19 
main   12 
main   13 
main   14 
Thread-1   12 
main   15 
Thread-1   13 
main   16 
Thread-1   14 
main   17 
Thread-1   15 
main   18 
main   19 
Thread-1   16 
main   0 
Thread-1   17 
main   1 
Thread-1   18 
Thread-1   19 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19
 
第二种结果: 
Thread-0   0 
Thread-1   0 
Thread-1   1 
Thread-1   2 
main   0 
Thread-1   3 
Thread-0   1 
Thread-0   2 
Thread-1   4 
main   1 
Thread-1   5 
Thread-1   6 
Thread-1   7 
Thread-0   3 
Thread-1   8 
Thread-1   9 
main   2 
Thread-1   10 
Thread-0   4 
Thread-1   11 
Thread-1   12 
main   3 
main   4 
Thread-1   13 
Thread-0   5 
Thread-1   14 
main   5 
Thread-1   15 
Thread-0   6 
Thread-0   7 
Thread-0   8 
Thread-0   9 
Thread-1   16 
main   6 
Thread-1   17 
Thread-0   10 
Thread-0   11 
Thread-1   18 
Thread-1   19 
main   7 
main   8 
main   9 
Thread-0   12 
Thread-0   13 
main   10 
Thread-0   14 
Thread-0   15 
Thread-0   16 
main   11 
Thread-0   17 
main   12 
Thread-0   18 
main   13 
Thread-0   19 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19
 
第三种结果: 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19 
Thread-1   0 
Thread-0   0 
Thread-1   1 
main   0 
main   1 
Thread-0   1 
main   2 
Thread-1   2 
Thread-1   3 
Thread-1   4 
main   3 
main   4 
Thread-0   2 
main   5 
Thread-1   5 
main   6 
Thread-0   3 
main   7 
Thread-1   6 
main   8 
Thread-0   4 
Thread-0   5 
main   9 
main   10 
main   11 
Thread-1   7 
main   12 
main   13 
main   14 
Thread-0   6 
main   15 
Thread-1   8 
main   16 
Thread-0   7 
main   17 
Thread-1   9 
main   18 
main   19 
Thread-0   8 
Thread-0   9 
main   0 
Thread-1   10 
main   1 
main   2 
Thread-0   10 
Thread-0   11 
Thread-0   12 
main   3 
Thread-1   11 
Thread-1   12 
Thread-1   13 
main   4 
Thread-0   13 
main   5 
Thread-1   14 
main   6 
Thread-0   14 
main   7 
Thread-1   15 
main   8 
main   9 
main   10 
Thread-0   15 
Thread-0   16 
main   11 
Thread-1   16 
main   12 
Thread-0   17 
main   13 
Thread-1   17 
main   14 
Thread-0   18 
main   15 
Thread-1   18 
Thread-1   19 
main   16 
Thread-0   19 
main   17 
main   18 
main   19
 
问题:为什么会产生这三种结果? 

例程4: 
Java代码  收藏代码
  1. public class TestThread {  
  2.     public static void main(String arg[]){  
  3.         NewThread t1 = new NewThread();  
  4.         NewThread t2 = new NewThread();  
  5.         Thread th1 = new Thread(t1);  
  6.         Thread th2 = new Thread(t2);  
  7.         for(int i = 0; i <20;i ++){  
  8.             System.out.println(Thread.currentThread().getName() +"   "+ i);  
  9.         }  
  10.         th1.run();  
  11.         th2.run();  
  12.     }  
  13. }  
  14. class NewThread implements Runnable{  
  15.     int i = 0;  
  16.     public void run() {  
  17.         for(int i = 0; i <20;i ++){  
  18.             System.out.println(Thread.currentThread().getName() +"   "+ i);  
  19.         }  
  20.     }  
  21. }  

程序运行结果如下: 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19 
main   0 
main   1 
main   2 
main   3 
main   4 
main   5 
main   6 
main   7 
main   8 
main   9 
main   10 
main   11 
main   12 
main   13 
main   14 
main   15 
main   16 
main   17 
main   18 
main   19
 
说明:在这种情况下才会产生惟一结果。线程对象直接调用run()方法,在主线程中顺序执行。 
### Java 中 `Thread` 的 `run()` 方法与 `start()` 方法区别及使用场景 #### 1. 基本概念 在 Java 的多线程编程中,`Thread` 提供了两个核心方法:`run()` `start()`。这两个方法的功能用途有显著差异。 - **`start()` 方法** 当调用 `start()` 方法时,它会触发 JVM 创建一个新的线程并执行该线程的任务[^1]。新线程一旦被创建,JVM 就会在后台自动调用 `run()` 方法来运行线程的具体逻辑。因此,`start()` 是真正用于启动线程的方法。 - **`run()` 方法** 这是一个普通的实例方法,通常由开发者重写以定义线程要执行的具体任务。如果直接调用 `run()` 方法而不是通过 `start()` 启动线程,则其行为似于普通方法调用,在当前线程上下文中执行,而不会开启新的线程[^3]。 #### 2. 工作机制对比 当调用 `start()` 方法时,JVM 执行以下操作: - 初始化新线程的相关资源。 - 切换到就绪状态等待 CPU 调度。 - 在获得调度权后,进入运行状态并通过内部机制调用 `run()` 方法完成实际工作[^4]。 然而,直接调用 `run()` 不涉及上述过程;它只是简单地作为常规函数被执行,无法实现真正的并发处理[^2]。 #### 3. 使用场景分析 以下是两种方法适用的不同情况: - **使用 `start()`** - 需要在独立的新线程里执行某些耗时或阻塞的操作。 - 实现程序内的并发控制,提高效率或者分离业务逻辑。 - **直接调用 `run()`** - 测试阶段快速验证 `run()` 内部代码逻辑是否正常运作而不必考虑多线程环境的影响。 - 特定情况下不需要利用额外线程仅需顺序执行某段流程时可采用这种方式简化开发复杂度。 #### 示例代码展示 下面给出一段基于前述理论的实际应用例子说明如何正确运用这两种方式: ```java public class MyTask extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName()+" says Hello!"); } public static void main(String[] args) throws InterruptedException{ MyTask task=new MyTask(); // 正确做法: 开启子线程 task.start(); /* 输出可能是(取决于CPU调度): Thread-0 says Hello! main continues... */ // 错误示范: 只是在主线程内模拟了单一线程的行为 task.run(); /* 输出总是: main says Hello! */ System.out.println("main continues..."); } } ``` #### 总结 综上所述,理解并区分 `start()` `run()` 对于掌握 Java 多线程至关重要。只有合理选用它们才能充分发挥多核处理器的优势从而构建高效稳定的软件系统。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值