继线程的创建和启动,这篇博文主要讨论一下start()和run()这两个方法。
1. run()方法
在线程的创建和启动的总结中有说过:根据java api,Thread类本身也是实现了Runnable接口,有:
public class Thread extends Object implements Runnable
现在来看一下Runnable接口,根据java api,Runnable接口只有一个方法,就是run():
“When an object implementing interface Runnable is used to create a thread, starting the thread causes the object’s run method to be called in that separately executing thread.”
“当通过实现Runnable接口来创建线程时,启动线程会使得run()方法在那个独立执行的线程中被调用。”
2. start()方法
根据java api,start()方法是Thread的类方法:
“Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.”
“start()方法会使得该线程开始执行;java虚拟机会去调用该线程的run()方法。”
因此,t.start()会导致run()方法被调用,run()方法中的内容称为线程体,它就是这个线程需要执行的工作。
用start()来启动线程,实现了真正意义上的启动线程,此时会出现异步执行的效果,即在线程的创建和启动中所述的随机性。‘
而如果使用run()来启动线程,就不是异步执行了,而是同步执行,不会达到使用线程的意义。
代码对比:
1.通过t.start()启动线程,JVM会自动调用该线程的run()方法
/*
* 通过实现Runnable接口创建线程
*/
public class MyThread_runnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+": Hello");
}
public static void main(String[] args) {
for(int i=0; i<10; i++){
System.out.println("创建一个线程");
MyThread_runnable r = new MyThread_runnable();
Thread t = new Thread(r);
System.out.println("启动线程");
t.start();
}
}
}
运行结果:
2.通过t.run()调用run()方法
public class MyThread_runnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+": Hello");
}
public static void main(String[] args) {
for(int i=0; i<10; i++){
System.out.println("创建一个线程");
MyThread_runnable r = new MyThread_runnable();
Thread t = new Thread(r);
System.out.println("启动线程");
t.run();
}
}
}
运行结果:
总结:
- 从运行结果肯明显可以看出,使用start()方法具有异步执行的效果,而使用run()方法是同步执行的效果,运行结果中规中矩。
- 使用start()方法,是真的启动了相应的线程0-9,而使用run()方法并没有真的启动线程,而是由一个叫main的主线程去调用的run()方法。
- 所以,正确启动线程的方式是使用start()方法。