经常看源码的大家应该都知道,Thread中包含了start和run两个方法,这两个方法都是用来启动线程的,那么他们到底有什么区别,我们来讲一讲…
是什么??
- start()方法是什么?
线程类的start方法可以用来启动线程,该方法会在内部调用Runnable接口的run方法,以在单独的线程中执行run方法中所指定的代码
启动线程执行的任务:- 统计一个新线程
- 线程从New state移动到Runnable状态
- 当线程有机会执行时,他的目标run方法将运行
- run()方法是什么??
- 线程类的run方法是Runnable接口的一个抽象方法,由虚拟机直接调用,不会创建新的线程
区别?!
start方法的作用是启动一个新线程,新线程会执行相应的run方法,start方法不能被重复调用
run方法就和普通的成员方法一样,可以被重复调用。单独调用run方法的话,会在当前线程中执行run,而不会去启动新的线程。
Public class MyThread extends Thread{
public void run(){
....//run方法实现
}
};
MyThread aaa=new MyThread();
当aaa执行start方法时,会创建一个新的线程,并在新的线程中使用run方法;而当aaa执行run方法的时候,则直接在当前线程中运行run方法,而不会启动一个新线程来运行run方法
样例
class MyThread extends Thread{
public MyThread(String name){
super(name);
}
public void run(){
System.out.println(Thread.currentThread().getName+"is running");
}
};
public class demo{
public static void main(String[] args){
Thread myThread=new MyThread("myThread");
System.out.println(Thread.currentThread.getName()+" call myThread.run()");
myThread.run();
System.out.println(Thread.currentThread.getName()+" call myThread.start()");
myThread.start();
}
}
执行结果:
main call myThread.run()
main is running;
main myThread.start();
myThread is running
说明:
(01) Thread.currentThread().getName()是用于获取“当前线程”的名字。当前线程是指正在cpu中调度执行的线程。
(02) mythread.run()是在“主线程main”中调用的,该run()方法直接运行在“主线程main”上。
(03) mythread.start()会启动“线程mythread”,“线程mythread”启动之后,会调用run()方法;此时的run()方法是运行在“线程mythread”上。
相关源码(jdk 8)
public synchronized void start() {
/**
* 对于主方法thread或“system”不调用此方法
* 由VM创建/设置的组线程。将来添加到这个方法中的任何新功能也可能必须添加到VM中。
*
* 零状态值对应于状态“新建”。
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/*通知组此线程即将启动,以便可以将其添加到组的线程列表中,并且可以减少组的未启动计数 */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* 什么都不做。如果start0抛出了一个异常,那么它将被传递到调用堆栈中 */
}
}
}
start()实际上是通过本地方法start0()启动线程的。而start0()会新运行一个线程,新线程会调用run()方法。
private native void start0();
public void run() {
if (target != null) {
target.run();
}
}
target是一个Runnable对象。run()直接调用Thread线程的Runnable成员的run()方法,不会新建线程。