我们知道,我们通过调用线程的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. 【leetcode刷题笔记】Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  2. bzoj5329 战略游戏

    有一个圆方树,每次给出一个点集,询问虚树上圆点数量-询问点数量 sol:题意读懂就很简单了...可以建虚树dp 也可以考虑每一条链对答案的贡献,最后要注意单独计算虚树根对答案的贡献 #pragma G ...

  3. luogu1901 发射站

    单调栈 正着插一遍反着插一遍 记录每个点左边右边第一个比他高的... yyc太强辣 #include<iostream> #include<cstdlib> #include& ...

  4. jcrop的bug

    1 360(7.1.1.620,内核:31.0.1650.63)的极速模式下,出现裁剪框后,鼠标点击,页面就会滑动到底部. 查看了下源码,发现是下面的代码: function watchKeys() ...

  5. java中toString() 、(String)、String.valueOf的区别

    1.采用toString() 在使用时要注意,必须保证object不是null值,否则将抛出NullPointerException异常.采用这种方法时,通常派生类会覆盖Object里的toStrin ...

  6. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

  7. bzoj2118

    最短路 很早以前做的了 数据范围太大,不能直接算 mn=min(a[i]) 算出d[i]表示sum%mn=i最小能构成的数,这个用最短路就行了,然后计算d[i],d[i]+mn的个数统计答案 #inc ...

  8. 问题:OAuth2.0;结果:帮你深入理解OAuth2.0协议

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题. 豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒 ...

  9. xdu2017校赛F

    Problem F Dogs of Qwordance Senior Backend R&D Engineers 问题描述 那年夏天,锘爷和杰师傅漫步在知春公园的小道上.他们的妻子.孩子牵 着 ...

  10. hbase->Mapreduce->hbase

    Hbase对Mapreduce API进行了扩展,方便Mapreduce任务读写HTable数据. package taglib.customer; import java.io.IOExceptio ...