A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zhangx 中级黑马   /  2013-4-17 19:37  /  1773 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我们学的知识是Thread类中重复调用start()方法,系统会抛出异常(如代码一),但代码二为什么不抛出异常?
代码一:
class MyThread extends Thread{        // 继承Thread类,作为线程的实现类
        private String name ;                // 表示线程的名称
        public MyThread(String name){
                this.name = name ;                // 通过构造方法配置name属性
        }
        public void run(){        // 覆写run()方法,作为线程 的操作主体
                for(int i=0;i<10;i++){
                        System.out.println(name + "运行,i = " + i) ;
                }
        }
};
public class ThreadDemo{
        public static void main(String args[]){
                MyThread mt1 = new MyThread("线程A ") ;         // 实例化对象
                mt1.start() ;        // 调用线程主体
                mt1.start() ;        // 重复调用
        }
};
代码二:
class MyThread extends Thread{        // 继承Thread类,作为线程的实现类
        public void run(){        // 覆写run()方法,作为线程 的操作主体
                for(int i=0;i<5;i++){               
                                System.out.println("你好") ;               
                }
        }
};
public class Demo{
        public static void main(String args[]){
                MyThread mt1 = new MyThread() ;         // 实例化对象       
                mt1.run() ;        // 调用线程主体
                mt1.run() ;        // 调用线程主体
                mt1.run() ;        // 调用线程主体

        }
};
同样是继承Thread类,为什么一个有异常一个没有异常?

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

5 个回复

倒序浏览
代码1:是多线程。
代码2:是单线程(主要主函数这个线程)

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
代码一:是调用线程。
因为线程里面定义了异常。所以需要抛出异常。

代码二:是调用方法。
所以不用抛出异常。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
因为线程是用start()启动的,而不是调用run()启动的。

第一种情况下,第一次调用start()方法时,线程是可以正常启动的,第二次调用的情况下,因为线程的状态已经改变了,所以会抛异常。
start()方法源代码如下:
  1. public synchronized void start() {
  2.         /**
  3.          * This method is not invoked for the main method thread or "system"
  4.          * group threads created/set up by the VM. Any new functionality added
  5.          * to this method in the future may have to also be added to the VM.
  6.          *
  7.          * A zero status value corresponds to state "NEW".
  8.          */
  9.         if (threadStatus != 0)
  10.             throw new IllegalThreadStateException();

  11.         /* Notify the group that this thread is about to be started
  12.          * so that it can be added to the group's list of threads
  13.          * and the group's unstarted count can be decremented. */
  14.         group.add(this);

  15.         boolean started = false;
  16.         try {
  17.             start0();
  18.             started = true;
  19.         } finally {
  20.             try {
  21.                 if (!started) {
  22.                     group.threadStartFailed(this);
  23.                 }
  24.             } catch (Throwable ignore) {
  25.                 /* do nothing. If start0 threw a Throwable then
  26.                   it will be passed up the call stack */
  27.             }
  28.         }
  29.     }
复制代码
可以看到方法开头的那个if判断结构,就是用来判断线程是否已经启动了的


第二种情况,只是单纯的调用run()方法而已,和调用其它普通方法没啥区别,只要方法本身没有错误,就不会报异常。

评分

参与人数 1技术分 +2 收起 理由
陈丽莉 + 2

查看全部评分

回复 使用道具 举报
不使用start()方法,启动的就不是多线程。代码二调用run()方法是单线程。运行时只有主线程一直在调用run()方法并不是像代码一中start()那样去创建一个线程。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
你的代码一属于多线程,因为你在数函数中用的是start()方法,这个方法是开启线程。
而你的代码二,则是直接掉用你这个 run(),并不是start()开启的,所以,代码而并不是一个多线程程序。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马