我们知道,我们通过调用线程的start方法启动一个线程,那么,我们可以直接调用run方法来启动一个线程吗?

先看下面一段代码:

  1. public class Test {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. TestThread tt = new TestThread();
  5. tt.run();
  6. }
  7. }
  8. class TestThread extends Thread {
  9. static int i = 0;
  10. final static int MAX_I = 10;
  11. @Override
  12. public void run() {
  13. // TODO Auto-generated method stub
  14. while (i < MAX_I) {
  15. System.out.println(i++);
  16. }
  17. }
  18. }

运行结果如下:

  1. 0
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9

或许有人会得出结论,这样启动一个线程是可以的,我们再对程式稍做修改,大家就会发现一个问题:

  1. public class Test {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. TestThread tt = new TestThread();
  5. tt.run();
  6. System.out.println("Printed by main thread");
  7. }
  8. }
  9. class TestThread extends Thread {
  10. static int i = 0;
  11. final static int MAX_I = 10;
  12. @Override
  13. public void run() {
  14. // TODO Auto-generated method stub
  15. while (i < MAX_I) {
  16. System.out.println(i++);
  17. }
  18. }
  19. }

这里只在主线程中加入了一行代码,打印一行"Printed by main thread",运行代码,结果如下:

  1. 0
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9
  11. Printed by main thread

熟练多线程开发的要发现问题了,为什么"Printed by main thread"会打印在最后一行呢?TestThread类中一直持有时间段吗?

我们对上面的代码进行分析,其实非常简单,这只是一个普通的类中方法的调用,其实是一个单线程的执行,我们来修改代码进一步验证这一点:

  1. public class Test {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. TestThread tt = new TestThread();
  5. tt.run();
  6. System.out.println(Thread.currentThread().getName());
  7. System.out.println("Printed by main thread");
  8. }
  9. }
  10. class TestThread extends Thread {
  11. static int i = 0;
  12. final static int MAX_I = 10;
  13. @Override
  14. public void run() {
  15. // TODO Auto-generated method stub
  16. System.out.println(Thread.currentThread().getName());
  17. while (i < MAX_I) {
  18. System.out.println(i++);
  19. }
  20. }
  21. }

这段代码分别在主线程和我们的TestThread的方法中打印当前线程名字,运行结果如下:

  1. main
  2. 0
  3. 1
  4. 2
  5. 3
  6. 4
  7. 5
  8. 6
  9. 7
  10. 8
  11. 9
  12. main
  13. Printed by main thread

在TestThread类和主线程中运行的是同一个线程,说明在直接调用run时是不能使用多线程的,那么把上面的run方法调用改为start方法的调动再看一下:

  1. public class Test {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. TestThread tt = new TestThread();
  5. tt.start();
  6. System.out.println(Thread.currentThread().getName());
  7. System.out.println("Printed by main thread");
  8. }
  9. }
  10. class TestThread extends Thread {
  11. static int i = 0;
  12. final static int MAX_I = 10;
  13. @Override
  14. public void run() {
  15. // TODO Auto-generated method stub
  16. System.out.println(Thread.currentThread().getName());
  17. while (i < MAX_I) {
  18. System.out.println(i++);
  19. }
  20. }
  21. }

运行结果如下:

  1. main
  2. Thread-0
  3. 0
  4. 1
  5. 2
  6. 3
  7. 4
  8. 5
  9. 6
  10. 7
  11. 8
  12. Printed by main thread
  13. 9

很明显,这才是我们想看到的结果,所以结论是只有调用Thread的start方法,将线程交由JVM控制,才能产生多线程,而直接调用run方法只是一个普通的单线程程式。

Java start和run启动线程的区别的更多相关文章

  1. Java Thread 的 run() 与 start() 的区别

    Java Thread 的使用 Java Thread 的 run() 与 start() 的区别 Java Thread 的 sleep() 和 wait() 的区别             1. ...

  2. Java并发编程:Java Thread 的 run() 与 start() 的区别

    1. sleep 和 wait 方法解释 sleep()方法是Thread类里面的,主要的意义就是让当前线程停止执行,让出cpu给其他的线程,但是不会释放对象锁资源以及监控的状态,当指定的时间到了之后 ...

  3. java Thread 类 run 和 start 方法区别

    public class ThreadModle { public static void main(String[] args) throws InterruptedException { Thre ...

  4. Java中Thread方法启动线程

    public class ThreadTest extends Thread {  private int count = 10; @Override public void run() { //重写 ...

  5. Java Thread 的 sleep() 和 wait() 的区别

    Java Thread 的使用 Java Thread 的 run() 与 start() 的区别 Java Thread 的 sleep() 和 wait() 的区别       1. sleep ...

  6. Java线程Run和Start的区别

    先上结论:run只是Thread里面的一个普通方法,start是启动线程的方法.何以见得呢?可以执行下面的代码看看run和start的区别: package com.basic.thread; /** ...

  7. 启动线程,start和run的区别

    每个线程都有要执行的任务.线程的任务处理逻辑可以在Tread类的run实例方法中直接实现或通过该方法进行调用,因此 run()相当于线程的任务处理逻辑的入口方法,它由Java虚拟机在运行相应线程时直接 ...

  8. JAVA面试题 启动线程是start()还是run()?为什么?

    面试官:请问启动线程是start()还是run()方法,能谈谈吗? 应聘者:start()方法 当用start()开始一个线程后,线程就进入就绪状态,使线程所代表的虚拟处理机处于可运行状态,这意味着它 ...

  9. java核心知识点学习----并发和并行的区别,进程和线程的区别,如何创建线程和线程的四种状态,什么是线程计时器

    多线程并发就像是内功,框架都像是外功,内功不足,外功也难得精要. 1.进程和线程的区别 一个程序至少有一个进程,一个进程至少有一个线程. 用工厂来比喻就是,一个工厂可以生产不同种类的产品,操作系统就是 ...

随机推荐

  1. Arc076_E Connected?

    传送门 题目大意 给定$H\times W$的网格$(W,H\leq 10^8)$上的$N$对顶点,即两线交叉的交叉点而非格子内部$(N\leq 10^5)$,求是否存在至少一种方案使得每对点之间都有 ...

  2. 每天一个linux命令(13):more命令

    版权声明更新:2017-05-17博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2. ...

  3. VC++6.0注释快捷键的添加使用

    在eclipse等编辑工具中都有注释代码的快捷键,但是vc++6.0没有. vc++是以VB为脚本来控制的,在网上找到了一个VB的脚本供大家使用.   工具/原料 VC++6.0 方法/步骤 打开VC ...

  4. Poj 2662,2909 Goldbach's Conjecture (素数判定)

    一.Description In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard ...

  5. Python:Iterable和Iterator

    转于:https://blog.csdn.net/whgqgq/article/details/63685066 博主:gongqi1992 iterable和iterator最基本的区别: iter ...

  6. JVM插庄之一:JVM字节码增强技术介绍及入门示例

    字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...

  7. JZ2440 启动NFS网络文件系统_初试led驱动

    http://blog.csdn.net/emdfans/article/details/12260969 u-boot ---> q 修改bootargs变量 默认: bootargs=noi ...

  8. 请定义一个宏,比较两个数的a、b的大小,不能使用大于、小于、if语句

    请定义一个宏,比较两个数的a.b的大小,不能使用大于.小于.if语句 方法一:    #define max(a,b) ((((long)((a)-(b)))&0x80000000)?(b): ...

  9. [#413c] Fountains

    http://codeforces.com/contest/799/problem/C 解题关键:树状数组取最大值,注意先搜索,后加入,此种情况可以取出最大值. 为什么可以取到最大值? 1.当分别用两 ...

  10. [转发]深入理解git,从研究git目录开始

    转发学习的啦. 似乎很少有人在读某个git快速教程的时候会说:“这个关于git的快速教程太酷了!读完了用起git来超级舒服,并且我一点也不怕自己会破坏什么东西.” 对git的初学者来说,刚接触git时 ...