1、两个方法的区别
start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。
run() : run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程。
举例说明:
class ThreadTest extends Thread{
public void run(){
...
}
};
然后假设在main方法中带创建了一个线程mythread
ThreadTest mythread = new ThreadTest ();
mythread .start()会启动一个新线程,并在新线程中运行run()方法。
而mythread .run()则会直接在当前线程(main方法对应的线程)中运行run()方法,并不会启动一个新线程来运行run()。
2、案例详解
输出结果: main call mythread.run() |
分析:
(1) Thread.currentThread().getName()是用于获取“当前线程”的名字。当前线程是指正在cpu中调度执行的线程。
(2) mythread.run()是在“主线程main”中调用的,该run()方法直接运行在“主线程main”上。
(3) mythread.start()会启动“线程mythread”,“线程mythread”启动之后,会调用run()方法;此时的run()方法是运行在“线程mythread”上。
3、重复调用start方法的结果
如果上述代码中,连续多次执行mythread.start();则会显示如下异常
Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:708) at thread.ThreadRunAndStart.main(ThreadRunAndStart.java:28) |
为什么会出现这种异常呢?查看源码可知,在调用start方法时,先检查线程的状态,如果不是“就绪状态”,也即线程状态值不是0,则抛出异常。Thread.java中start()方法的源码如下:
public synchronized void start() { // 将线程添加到ThreadGroup中 boolean started = false; 说明:start()实际上是通过本地方法start0()启动线程的。而start0()会新运行一个线程,新线程会调用run()方法(也即新建一个线程,并且调用线程的run方法)。 |
Thread.java中run()方法的源码如下:
target是一个Runnable对象。run()就是直接调用Thread线程的Runnable成员的run()方法,并不会新建一个线程(所以直接调用run方法,不会创建新的线程,直接在当前线程中调用run方法)。 |